8cf877ab0c9ff3803be173a06a493f5abac6ac09
[scilab.git] / scilab / modules / ast / src / cpp / ast / visitor_common.cpp
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 #include <string>
14 #include <numeric>
15 #include "visitor_common.hxx"
16 #include "exp.hxx"
17 #include "fieldexp.hxx"
18 #include "simplevar.hxx"
19 #include "callexp.hxx"
20 #include "struct.hxx"
21 #include "context.hxx"
22 #include "execvisitor.hxx"
23 #include "serializervisitor.hxx"
24 #include "deserializervisitor.hxx"
25 #include "localization.hxx"
26 #include "user.hxx"
27
28 #include "alltypes.hxx"
29
30 size_t ast::Ast::globalNodeNumber = 0;
31
32 /*
33  * Generate destination variable from _poSource type and size parameters
34  */
35 types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _iCols)
36 {
37     types::InternalType* poResult = NULL;
38     switch (_poSource->getType())
39     {
40         case types::GenericType::ScilabDouble :
41             poResult = new types::Double(_iRows, _iCols, false);
42             break;
43         case types::GenericType::ScilabBool :
44             poResult = new types::Bool(_iRows, _iCols);
45             break;
46         case types::GenericType::ScilabInt8 :
47             poResult = new types::Int8(_iRows, _iCols);
48             break;
49         case types::GenericType::ScilabUInt8 :
50             poResult = new types::UInt8(_iRows, _iCols);
51             break;
52         case types::GenericType::ScilabInt16 :
53             poResult = new types::Int16(_iRows, _iCols);
54             break;
55         case types::GenericType::ScilabUInt16 :
56             poResult = new types::UInt16(_iRows, _iCols);
57             break;
58         case types::GenericType::ScilabInt32 :
59             poResult = new types::Int32(_iRows, _iCols);
60             break;
61         case types::GenericType::ScilabUInt32 :
62             poResult = new types::UInt32(_iRows, _iCols);
63             break;
64         case types::GenericType::ScilabInt64 :
65             poResult = new types::Int64(_iRows, _iCols);
66             break;
67         case types::GenericType::ScilabUInt64 :
68             poResult = new types::UInt64(_iRows, _iCols);
69             break;
70         case types::GenericType::ScilabString :
71             poResult = new types::String(_iRows, _iCols);
72             break;
73         case types::GenericType::ScilabPolynom :
74         {
75             int* piRank = new int[_iRows * _iCols];
76             memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
77             poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
78             delete[] piRank;
79             break;
80         }
81         case types::InternalType::ScilabImplicitList :
82             poResult = new types::ImplicitList();
83             break;
84         default :
85             // FIXME : What should we do here ??
86             break;
87     }
88     return poResult;
89 }
90
91 types::InternalType* AddElementToVariableFromCol(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piCols)
92 {
93     types::InternalType *poResult               = NULL;
94     types::InternalType::ScilabType TypeSource  = _poSource->getType();
95     types::InternalType::ScilabType TypeDest    = types::InternalType::ScilabInternal;
96
97     if (_poDest == NULL)
98     {
99         //First call, alloc _poSource
100         poResult = allocDest(_poSource, _iRows, _iCols);
101         TypeDest = TypeSource;
102     }
103     else
104     {
105         TypeDest = _poDest->getType();
106         poResult = _poDest;
107     }
108
109     if (TypeDest != TypeSource)
110     {
111         //check if source type is compatible with dest type
112     }
113     else
114     {
115         switch (TypeDest)
116         {
117             case types::GenericType::ScilabDouble :
118                 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
119                 {
120                     poResult->getAs<types::Double>()->setComplex(true);
121                 }
122
123                 poResult->getAs<types::Double>()->fillFromCol(*_piCols, _poSource->getAs<types::Double>());
124                 *_piCols += _poSource->getAs<types::Double>()->getCols();
125
126                 break;
127             default:
128                 break;
129         }
130         return poResult;
131     }
132     return NULL;
133 }
134
135 types::InternalType* AddElementToVariableFromRow(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piRows)
136 {
137     types::InternalType *poResult               = NULL;
138     types::InternalType::ScilabType TypeSource  = _poSource->getType();
139     types::InternalType::ScilabType TypeDest    = types::InternalType::ScilabInternal;
140
141     if (_poDest == NULL)
142     {
143         //First call, alloc _poSource
144         poResult = allocDest(_poSource, _iRows, _iCols);
145         TypeDest = TypeSource;
146     }
147     else
148     {
149         TypeDest = _poDest->getType();
150         poResult = _poDest;
151     }
152
153
154     if (TypeDest != TypeSource)
155     {
156         //check if source type is compatible with dest type
157     }
158     else
159     {
160         switch (TypeDest)
161         {
162             case types::GenericType::ScilabDouble :
163                 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
164                 {
165                     poResult->getAs<types::Double>()->setComplex(true);
166                 }
167
168                 poResult->getAs<types::Double>()->fillFromRow(*_piRows, _poSource->getAs<types::Double>());
169                 *_piRows += _poSource->getAs<types::Double>()->getRows();
170
171                 break;
172             default:
173                 break;
174         }
175         return poResult;
176     }
177     return NULL;
178 }
179
180
181 /*
182 _iRows : Position if _poDest allready initialized else size of the matrix
183 _iCols : Position if _poDest allready initialized else size of the matrix
184 */
185 types::InternalType* AddElementToVariable(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols)
186 {
187     types::InternalType *poResult = NULL;
188     types::InternalType::ScilabType TypeSource = _poSource->getType();
189     types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
190     int iCurRow = _iRows;
191     int iCurCol = _iCols;
192
193     if (_poDest == NULL)
194     {
195         switch (TypeSource)
196         {
197             case types::GenericType::ScilabDouble :
198                 poResult = new types::Double(_iRows, _iCols, false);
199                 break;
200             case types::GenericType::ScilabBool :
201                 poResult = new types::Bool(_iRows, _iCols);
202                 break;
203             case types::GenericType::ScilabInt8 :
204                 poResult = new types::Int8(_iRows, _iCols);
205                 break;
206             case types::GenericType::ScilabUInt8 :
207                 poResult = new types::UInt8(_iRows, _iCols);
208                 break;
209             case types::GenericType::ScilabInt16 :
210                 poResult = new types::Int16(_iRows, _iCols);
211                 break;
212             case types::GenericType::ScilabUInt16 :
213                 poResult = new types::UInt16(_iRows, _iCols);
214                 break;
215             case types::GenericType::ScilabInt32 :
216                 poResult = new types::Int32(_iRows, _iCols);
217                 break;
218             case types::GenericType::ScilabUInt32 :
219                 poResult = new types::UInt32(_iRows, _iCols);
220                 break;
221             case types::GenericType::ScilabInt64 :
222                 poResult = new types::Int64(_iRows, _iCols);
223                 break;
224             case types::GenericType::ScilabUInt64 :
225                 poResult = new types::UInt64(_iRows, _iCols);
226                 break;
227             case types::GenericType::ScilabString :
228                 poResult = new types::String(_iRows, _iCols);
229                 break;
230             case types::GenericType::ScilabSparse :
231                 poResult = new types::Sparse(_iRows, _iCols);
232                 break;
233             case types::GenericType::ScilabSparseBool :
234                 poResult = new types::SparseBool(_iRows, _iCols);
235                 break;
236             case types::GenericType::ScilabPolynom :
237             {
238                 int* piRank = new int[_iRows * _iCols];
239                 memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
240                 poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
241                 delete[] piRank;
242                 break;
243             }
244             case types::InternalType::ScilabImplicitList :
245                 poResult = new types::ImplicitList();
246                 break;
247             case types::GenericType::ScilabHandle :
248                 poResult = new types::GraphicHandle(_iRows, _iCols);
249                 break;
250             default :
251                 // FIXME What should we do here ...
252                 break;
253         }
254         iCurCol = 0;
255         iCurRow = 0;
256         TypeDest =    TypeSource;
257     }
258     else
259     {
260         TypeDest = _poDest->getType();
261         poResult = _poDest;
262     }
263
264
265     if (TypeDest != TypeSource)
266     {
267         //check if source type is compatible with dest type
268         switch (TypeDest)
269         {
270             case types::GenericType::ScilabDouble :
271                 if (TypeSource == types::GenericType::ScilabPolynom)
272                 {
273                     types::Double *poDest = _poDest->getAs<types::Double>();
274                     Polynom* pPSource = _poSource->getAs<types::Polynom>();
275
276                     //Convert Dest to ScilabPolynom
277                     int iSize = poDest->getSize();
278                     int *piRank = new int[iSize];
279                     memset(piRank, 0x00, iSize * sizeof(int));
280                     poResult = new types::Polynom(pPSource->getVariableName(), poDest->getRows(), poDest->getCols(), piRank);
281                     delete[] piRank;
282
283                     Polynom* pPResult = poResult->getAs<types::Polynom>();
284                     pPResult->setComplex(poDest->isComplex());
285
286                     double *pR = poDest->getReal();
287                     SinglePoly** pSP = pPResult->get();
288
289                     if (poDest->isComplex())
290                     {
291                         double *pI = poDest->getImg();
292                         for (int i = 0 ; i < iSize; i++)
293                         {
294                             pSP[i]->set(0, pR[i]);
295                             pSP[i]->setImg(0, pI[i]);
296                         }
297                     }
298                     else
299                     {
300                         for (int i = 0 ; i < iSize; i++)
301                         {
302                             pSP[i]->set(0, pR[i]);
303                         }
304                     }
305
306                     for (int i = 0 ; i < pPSource->getRows() ; i++)
307                     {
308                         for (int j = 0 ; j < pPSource->getCols() ; j++)
309                         {
310                             pPResult->set(iCurRow + i, iCurCol + j, pPSource->get(i, j));
311                         }
312                     }
313
314                     return poResult;
315                 }
316                 break;
317             case types::GenericType::ScilabPolynom :
318                 if (TypeSource == types::GenericType::ScilabDouble)
319                 {
320                     //Add Source like coef of the new element
321                     Double* pD = _poSource->getAs<Double>();
322                     types::Polynom* pPolyOut = poResult->getAs<types::Polynom>();
323
324                     if (pD->isComplex())
325                     {
326                         pPolyOut->setComplex(true);
327                         for (int i = 0 ; i < pD->getRows() ; i++)
328                         {
329                             for (int j = 0 ; j < pD->getCols() ; j++)
330                             {
331                                 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
332
333                                 pSPOut->setRank(0);
334                                 double pDblR = pD->get(i, j);
335                                 double pDblI = pD->getImg(i, j);
336                                 pSPOut->setCoef(&pDblR, &pDblI);
337                             }
338                         }
339                     }
340                     else
341                     {
342                         for (int i = 0 ; i < pD->getRows() ; i++)
343                         {
344                             for (int j = 0 ; j < pD->getCols() ; j++)
345                             {
346                                 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
347
348                                 pSPOut->setRank(0);
349                                 double pDbl = pD->get(i, j);
350                                 pSPOut->setCoef(&pDbl, NULL);
351                             }
352                         }
353                     }
354
355                     return poResult;
356                 }
357                 break;
358             case types::GenericType::ScilabSparse :
359                 if (TypeSource == types::GenericType::ScilabDouble)
360                 {
361                     types::Double* poSource = _poSource->getAs<types::Double>();
362                     types::Sparse* spResult = poResult->getAs<types::Sparse>();
363
364                     // Set complex the result if one of inputs is complex
365                     if (poSource->isComplex())
366                     {
367                         if (spResult->isComplex() == false)
368                         {
369                             spResult->toComplex();
370                         }
371                     }
372
373                     // Add poSource at the end of spResult
374                     if (spResult->isComplex())
375                     {
376                         if (poSource->isComplex())
377                         {
378                             for (int i = 0; i < poSource->getRows(); i++)
379                             {
380                                 for (int j = 0; j < poSource->getCols(); j++)
381                                 {
382                                     double dbl = poSource->get(i, j);
383                                     double dblImg = poSource->getImg(i, j);
384                                     if (dbl != 0 || dblImg != 0)
385                                     {
386                                         spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, dblImg));
387                                     }
388                                 }
389                             }
390                         }
391                         else
392                         {
393                             for (int i = 0; i < poSource->getRows(); i++)
394                             {
395                                 for (int j = 0; j < poSource->getCols(); j++)
396                                 {
397                                     double dbl = poSource->get(i, j);
398                                     if (dbl != 0)
399                                     {
400                                         spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, 0));
401                                     }
402                                 }
403                             }
404                         }
405                     }
406                     else
407                     {
408                         for (int i = 0; i < poSource->getRows(); i++)
409                         {
410                             for (int j = 0; j < poSource->getCols(); j++)
411                             {
412                                 double dbl = poSource->get(i, j);
413                                 if (dbl != 0)
414                                 {
415                                     spResult->set(i + iCurRow, j + iCurCol, dbl);
416                                 }
417                             }
418                         }
419                     }
420
421                     return poResult;
422                 }
423                 break;
424             case types::GenericType::ScilabSparseBool :
425                 if (TypeSource == types::GenericType::ScilabBool)
426                 {
427                     types::Bool* poSource = _poSource->getAs<types::Bool>();
428                     types::SparseBool* spResult = poResult->getAs<types::SparseBool>();
429
430                     // Add poSource at the end of spResult
431                     for (int i = 0; i < poSource->getRows(); i++)
432                     {
433                         for (int j = 0; j < poSource->getCols(); j++)
434                         {
435                             bool bValue = poSource->get(i, j) != 0;
436                             if (bValue)
437                             {
438                                 spResult->set(i + iCurRow, j + iCurCol, true);
439                             }
440                         }
441                     }
442
443                     return poResult;
444                 }
445                 break;
446             default:
447                 break;
448         }
449         // call overload
450         return NULL;
451     }
452     else
453     {
454         //Just add the new value in the current item
455         switch (TypeDest)
456         {
457             case types::GenericType::ScilabDouble :
458                 ((Double*)poResult)->append(iCurRow, iCurCol, (Double*)_poSource);
459                 break;
460             case types::GenericType::ScilabPolynom :
461                 poResult->getAs<types::Polynom>()->append(iCurRow, iCurCol, _poSource->getAs<types::Polynom>());
462                 break;
463             case types::GenericType::ScilabBool:
464                 poResult->getAs<types::Bool>()->append(iCurRow, iCurCol, _poSource->getAs<types::Bool>());
465                 break;
466             case types::GenericType::ScilabInt8 :
467                 poResult->getAs<types::Int8>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int8>());
468                 break;
469             case types::GenericType::ScilabUInt8 :
470                 poResult->getAs<types::UInt8>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt8>());
471                 break;
472             case types::GenericType::ScilabInt16 :
473                 poResult->getAs<types::Int16>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int16>());
474                 break;
475             case types::GenericType::ScilabUInt16 :
476                 poResult->getAs<types::UInt16>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt16>());
477                 break;
478             case types::GenericType::ScilabInt32 :
479                 poResult->getAs<types::Int32>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int32>());
480                 break;
481             case types::GenericType::ScilabUInt32 :
482                 poResult->getAs<types::UInt32>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt32>());
483                 break;
484             case types::GenericType::ScilabInt64 :
485                 poResult->getAs<types::Int64>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int64>());
486                 break;
487             case types::GenericType::ScilabUInt64 :
488                 poResult->getAs<types::UInt64>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt64>());
489                 break;
490             case types::GenericType::ScilabSparse :
491                 poResult->getAs<types::Sparse>()->append(iCurRow, iCurCol, _poSource->getAs<types::Sparse>());
492                 break;
493             case types::GenericType::ScilabSparseBool :
494                 poResult->getAs<types::SparseBool>()->append(iCurRow, iCurCol, _poSource->getAs<types::SparseBool>());
495                 break;
496             case types::GenericType::ScilabString :
497             {
498                 types::String* pSource = _poSource->getAs<types::String>();
499                 poResult->getAs<types::String>()->append(iCurRow, iCurCol, pSource);
500             }
501             break;
502             case types::GenericType::ScilabImplicitList :
503             {
504                 if (_poSource->getAs<ImplicitList>()->getStartType() == types::InternalType::ScilabPolynom)
505                 {
506                     poResult->getAs<ImplicitList>()->setStart(_poSource->getAs<ImplicitList>()->getStart());
507                 }
508                 else
509                 {
510                     poResult->getAs<ImplicitList>()->setStart(_poSource->getAs<ImplicitList>()->getStart());
511                 }
512
513                 if (_poSource->getAs<ImplicitList>()->getStepType() == types::InternalType::ScilabPolynom)
514                 {
515                     poResult->getAs<ImplicitList>()->setStep(_poSource->getAs<ImplicitList>()->getStep());
516                 }
517                 else
518                 {
519                     poResult->getAs<ImplicitList>()->setStep(_poSource->getAs<ImplicitList>()->getStep());
520                 }
521
522                 if (_poSource->getAs<ImplicitList>()->getEndType() == types::InternalType::ScilabPolynom)
523                 {
524                     poResult->getAs<ImplicitList>()->setEnd(_poSource->getAs<ImplicitList>()->getEnd());
525                 }
526                 else
527                 {
528                     poResult->getAs<ImplicitList>()->setEnd(_poSource->getAs<ImplicitList>()->getEnd());
529                 }
530                 break;
531             }
532             case types::GenericType::ScilabHandle :
533                 poResult->getAs<types::GraphicHandle>()->append(iCurRow, iCurCol, _poSource->getAs<types::GraphicHandle>());
534                 break;
535             default:
536                 // call overload
537                 return NULL;
538         }
539         return poResult;
540     }
541 }
542
543 const std::wstring* getStructNameFromExp(const ast::Exp* _pExp)
544 {
545     const ast::FieldExp* pField =  dynamic_cast<const ast::FieldExp*>(_pExp);
546     const ast::SimpleVar* pVar =  dynamic_cast<const ast::SimpleVar*>(_pExp);
547     const ast::CallExp* pCall =  dynamic_cast<const ast::CallExp*>(_pExp);
548
549     if (pField)
550     {
551         return getStructNameFromExp(pField->getHead());
552     }
553     else if (pVar)
554     {
555         return &(pVar->getSymbol().getName());
556     }
557     else if (pCall)
558     {
559         return getStructNameFromExp(&(pCall->getName()));
560     }
561     else
562     {
563         std::wostringstream os;
564         os << _W("Unknow expression");
565         //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
566         throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
567     }
568     return NULL;
569 }
570
571 /*** overload insertion                 ||         extraction       ***/
572 //%x_i_x(i1, i2, ..., in, source, dest) || %x_e(i1, i2, ..., in, source, dest)
573 //i1, ..., in : indexes
574 //dest : variable where insert data     || NULL
575 //source : data to insert               || extract indexes from source
576 types::InternalType* callOverload(const ast::Exp& e, std::wstring _strType, types::typed_list* _pArgs, types::InternalType* _source, types::InternalType* _dest)
577 {
578     types::InternalType* pITOut = NULL;
579     types::typed_list in;
580     types::typed_list out;
581
582     std::wstring function_name;
583     function_name = L"%" + _source->getShortTypeStr() + L"_" + _strType;
584
585     for (int i = 0; i < (int)_pArgs->size(); i++)
586     {
587         (*_pArgs)[i]->IncreaseRef();
588         in.push_back((*_pArgs)[i]);
589     }
590
591     _source->IncreaseRef();
592     in.push_back(_source);
593
594     if (_dest)
595     {
596         _dest->IncreaseRef();
597         in.push_back(_dest);
598
599         function_name += L"_" + _dest->getShortTypeStr();
600     }
601
602     InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
603     // if %type_6 doesn't exist, call %l_6
604     if (_dest == NULL && pFunc == NULL)
605     {
606         function_name = L"%l_" + _strType;
607     }
608
609     // For insertion in TList, call normal insertion if overload doesn't exits
610     if ((_dest  && _dest->isTList() && pFunc == NULL) == false || _source->isListDelete())
611     {
612         ast::ExecVisitor exec;
613         if (Overload::call(function_name, in, 1, out, &exec))
614         {
615             //manage error
616             std::wostringstream os;
617             os << _W("Error in overload function: ") << function_name << std::endl;
618             throw ast::ScilabError(os.str(), 999, e.getLocation());
619         }
620     }
621
622     for (int i = 0; i < (int)_pArgs->size(); i++)
623     {
624         (*_pArgs)[i]->DecreaseRef();
625     }
626
627     _source->DecreaseRef();
628     if (_dest)
629     {
630         _dest->DecreaseRef();
631     }
632
633     if (out.size() == 1)
634     {
635         pITOut = out[0];
636     }
637     else if (out.size() > 1)
638     {
639         List* pListOut = new List();
640         for (int i = 0; i < (int)out.size(); i++)
641         {
642             pListOut->append(out[i]);
643         }
644
645         pITOut = pListOut;
646     }
647
648     return pITOut;
649 }
650
651
652 bool getFieldsFromExp(ast::Exp* _pExp, std::list<ExpHistory*>& fields)
653 {
654     ast::FieldExp* pField      = dynamic_cast<ast::FieldExp*>(_pExp);
655     ast::SimpleVar* pVar       = dynamic_cast<ast::SimpleVar*>(_pExp);
656     ast::CallExp* pCall        = dynamic_cast<ast::CallExp*>(_pExp);
657     ast::CellCallExp* pCell    = dynamic_cast<ast::CellCallExp*>(_pExp);
658
659     if (pField)
660     {
661         if (getFieldsFromExp(pField->getHead(), fields))
662         {
663             return getFieldsFromExp(pField->getTail(), fields);
664         }
665
666         return false;
667     }
668     else if (pVar)
669     {
670         if (fields.empty())
671         {
672             fields.push_back(new ExpHistory(NULL, pVar));
673         }
674         else
675         {
676             ExpHistory * pEHParent = fields.back();
677             ExpHistory * pEH = new ExpHistory(pEHParent, pVar);
678             pEH->setLevel(pEHParent->getLevel() + 1);
679             fields.push_back(pEH);
680         }
681
682         return true;
683     }
684     else if (pCall)
685     {
686         ast::ExecVisitor execMe;
687         typed_list* pCurrentArgs = execMe.GetArgumentList(pCall->getArgs());
688
689         bool bErr = getFieldsFromExp(&pCall->getName(), fields);
690         if (pCurrentArgs                    &&
691                 pCurrentArgs->size() == 1       &&
692                 (*pCurrentArgs)[0]->isString()  &&
693                 (*pCurrentArgs)[0]->getAs<String>()->getSize() == 1)
694         {
695             // a("b") => a.b or a(x)("b") => a(x).b
696             ExpHistory * pEHParent = fields.back();
697             ast::SimpleVar* pFieldVar = new ast::SimpleVar(pCall->getLocation(), *new symbol::Symbol((*pCurrentArgs)[0]->getAs<String>()->get(0)));
698             ExpHistory * pEH = new ExpHistory(pEHParent, pFieldVar);
699             pEH->setLevel(pEHParent->getLevel() + 1);
700             pEH->setExpOwner(true);
701
702             (*pCurrentArgs)[0]->killMe();
703             delete pCurrentArgs;
704
705             fields.push_back(pEH);
706         }
707         else if (fields.back()->getArgs())
708         {
709             // a(x)(y)(z)
710             ExpHistory * pEHParent = fields.back();
711             ExpHistory * pEH = new ExpHistory(pEHParent, pCurrentArgs);
712             pEH->setLevel(pEHParent->getLevel() + 1);
713             pEH->setArgsOwner(true);
714             fields.push_back(pEH);
715         }
716         else
717         {
718             // a(x)
719             fields.back()->setArgs(pCurrentArgs);
720             fields.back()->setArgsOwner(true);
721         }
722
723         if (pCell)
724         {
725             // a{x}
726             fields.back()->setCellExp();
727         }
728
729         return bErr;
730     }
731     else
732     {
733         return false;
734     }
735 }
736
737 types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fields, InternalType* _pAssignValue)
738 {
739     std::list<ExpHistory*> evalFields;
740
741     //*** get main variable ***//
742     std::list<ExpHistory*>::iterator iterFields = fields.begin();
743     ExpHistory* pFirstField = *iterFields;
744     InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
745     if (pIT == NULL)
746     {
747         if (pFirstField->isCellExp())
748         {
749             // a{x}, where "a" doesn't exists
750             pIT = new Cell(1, 1);
751             symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
752         }
753         else if (fields.size() > 1)
754         {
755             // is a field exp
756             //"a" does not exist or it is another type, create it with size 1,1 and return it
757             //create new structure variable
758             pIT = new Struct(1, 1);
759             symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
760         }
761         // else
762         // is a call exp
763         // a(x) = "something" and a does not exist
764         // a will be create in insertionCall
765     }
766     else if (pIT->getRef() > 1 && pIT->isHandle() == false)
767     {
768         pIT = pIT->clone();
769         symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
770     }
771     else if (pIT == _pAssignValue)
772     {
773         // clone me before insert me in myself.
774         // ie : a.b = 2; a.b.c.d = a;
775         _pAssignValue = _pAssignValue->clone();
776     }
777
778     iterFields++;
779
780     std::list<ExpHistory*> workFields;
781     workFields.push_back(new ExpHistory(NULL,
782                                         pFirstField->getExp(),
783                                         pFirstField->getArgs(),
784                                         pFirstField->getLevel(),
785                                         pFirstField->isCellExp(),
786                                         pIT));
787
788     //*** evaluate fields ***//
789     while (iterFields != fields.end())
790     {
791         ExpHistory* pEH = workFields.front();
792         evalFields.push_back(pEH);
793         workFields.pop_front();
794
795         types::InternalType* pITCurrent = pEH->getCurrent();
796
797         if (pEH->isCellExp() && pITCurrent->isCell() == false)
798         {
799             std::wostringstream os;
800             os << _W("Wrong insertion : use extraction with {} only on a Cell.");
801             throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
802         }
803
804         if (pITCurrent->isStruct())
805         {
806             Struct* pStruct = pITCurrent->getAs<Struct>();
807             std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
808
809             if (pEH->needResize())
810             {
811                 if (pEH->getArgsDims() == 1)
812                 {
813                     std::wostringstream os;
814                     os << _W("Invalid index.");
815                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
816                 }
817
818                 // resize current struct
819                 pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
820             }
821
822             // create field in parent if it not exist
823             if (pStruct->exists(pwcsFieldname) == false)
824             {
825                 pStruct->addField(pwcsFieldname);
826             }
827
828             if (pEH->getArgs())
829             {
830                 InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
831                 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
832             }
833             else
834             {
835                 // extract field x and append it to elements for next recursion.
836                 List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
837                 for (int iList = 0; iList < pLOut->getSize(); iList++)
838                 {
839                     InternalType* pIT = pLOut->get(iList);
840                     if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
841                     {
842                         // clone element before modify it.
843                         //pIT->DecreaseRef();
844                         pIT = pIT->clone();
845                         pStruct->get(iList)->set(pwcsFieldname, pIT);
846                     }
847
848                     ExpHistory* pEHChield = new ExpHistory( pEH,
849                                                             (*iterFields)->getExp(),
850                                                             (*iterFields)->getArgs(),
851                                                             (*iterFields)->getLevel(),
852                                                             (*iterFields)->isCellExp(),
853                                                             pIT);
854                     pEHChield->setWhereReinsert(iList);
855                     workFields.push_back(pEHChield);
856                 }
857
858                 pLOut->killMe();
859             }
860         }
861         else if (pITCurrent->isTList() || pITCurrent->isMList())
862         {
863             TList* pTL = pITCurrent->getAs<TList>();
864             typed_list* pArgs = pEH->getArgs();
865             if (pArgs)
866             {
867                 if (pArgs->size() > 1 || pITCurrent->isMList())
868                 {
869                     // call overload
870                     InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
871                     if ((*iterFields)->getExp() == NULL)
872                     {
873                         // a(x)(y)
874                         // extract a(x) and push_BACK to extract y
875                         workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
876                         workFields.back()->setReinsertion();
877                     }
878                     else
879                     {
880                         // a(x).b
881                         // extract a(x) and push_FRONT to extract b
882                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
883                         workFields.front()->setReinsertion();
884                     }
885                 }
886                 else
887                 {
888                     // resize TList
889                     int iNewSize = pEH->getSizeFromArgs();
890                     if (pTL->getSize() < iNewSize)
891                     {
892                         pTL->set(iNewSize - 1, new ListUndefined());
893                     }
894
895                     // update pArgs variables with new argument computed in getSizeFromArgs
896                     pArgs = pEH->getArgs();
897
898                     InternalType* pIT = pTL->extract(pArgs);
899                     List* pList = pIT->getAs<List>();
900                     double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
901
902                     if ((*iterFields)->getExp() == NULL)
903                     {
904                         // a(x)(y)
905                         // extract a(x) and push_BACK to extract y
906                         for (int i = 0; i < pList->getSize(); i++)
907                         {
908                             ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(i));
909                             pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
910                             workFields.push_back(pEHExtract);
911                         }
912                     }
913                     else
914                     {
915                         // a(x).b
916                         // extract a(x) and push_FRONT to extract b
917                         for (int i = 0; i < pList->getSize(); i++)
918                         {
919                             ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(i));
920                             pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
921                             workFields.push_front(pEHExtract);
922                         }
923                     }
924                 }
925             }
926             else
927             {
928                 // get string "x" of a.x
929                 InternalType* pExtract = NULL;
930                 std::wstring pwcsFieldname = L"";
931                 bool bReinsert = false;
932                 ExpHistory* pEHChield = NULL;
933
934                 pwcsFieldname = (*iterFields)->getExpAsString();
935
936                 // check if field exists
937                 if (pTL->exists(pwcsFieldname) == false)
938                 {
939                     std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
940                     ++iterFieldsNext;
941
942                     if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
943                     {
944                         // M=mlist(['MType','x','y'], ...
945                         // M.rows1 = "somthing"
946                         pArgs = new typed_list();
947                         pArgs->push_back(new String(pwcsFieldname.c_str()));
948
949                         // call overload
950                         pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
951                         bReinsert = true;
952
953                         delete pArgs;
954                     }
955                 }
956                 else
957                 {
958                     // extract field x and append it to elements for next recursion.
959                     pExtract = pTL->getField(pwcsFieldname);
960                 }
961
962                 pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
963                 workFields.push_back(pEHChield);
964
965                 if (bReinsert)
966                 {
967                     pEHChield->setReinsertion();
968                 }
969             }
970         }
971         else if (pITCurrent->isList())
972         {
973             List* pL = pITCurrent->getAs<List>();
974             if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
975             {
976                 // pITCurrent is an extraction of other Type
977                 for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
978                 {
979                     ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
980                     pEHExtract->setWhereReinsert(iLoop);
981                     workFields.push_front(pEHExtract);
982                 }
983             }
984             else
985             {
986                 // pITCurrent is a field
987                 if (pEH->getArgs())
988                 {
989                     if (pEH->getArgs()->size() > 1)
990                     {
991                         // call overload
992                         InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
993
994                         if ((*iterFields)->getExp() == NULL)
995                         {
996                             // a(x)(y)
997                             // extract a(x) and push_BACK to extract next level
998                             workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
999                             workFields.back()->setReinsertion();
1000                         }
1001                         else
1002                         {
1003                             // a(x).b
1004                             // extract a(x) and push_FRONT to extract b from a(x)
1005                             workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1006                             workFields.front()->setReinsertion();
1007                         }
1008                     }
1009                     else
1010                     {
1011                         // resize List
1012                         int iNewSize = pEH->getSizeFromArgs();
1013                         if (pL->getSize() < iNewSize)
1014                         {
1015                             pL->set(iNewSize - 1, new ListUndefined());
1016                         }
1017
1018                         Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
1019                         double* pdblArgs = pDblArgs->get();
1020
1021                         if ((*iterFields)->getExp() == NULL)
1022                         {
1023                             // a(x)(y) => a.b(y)
1024                             // extract a(x) and push_BACK to extract next level
1025                             for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1026                             {
1027                                 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1028                                 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1029                                 workFields.push_back(pEHExtract);
1030                             }
1031                         }
1032                         else
1033                         {
1034                             // a(x).b
1035                             // extract a(x) and push_FRONT to extract b from a(x)
1036                             for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1037                             {
1038                                 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1039                                 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1040                                 workFields.push_front(pEHExtract);
1041                             }
1042                         }
1043                     }
1044                 }
1045                 else
1046                 {
1047                     // a.x, get string "x"
1048                     std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1049
1050                     // call overload
1051                     typed_list* args = new typed_list();
1052                     args->push_back(new String(pwcsFieldname.c_str()));
1053                     pEH->setArgs(args);
1054
1055                     InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
1056
1057                     // append extraction of a.x for next level.
1058                     workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1059                     workFields.back()->setReinsertion();
1060                 }
1061             }
1062         }
1063         else if (pITCurrent->isHandle())
1064         {
1065             // call overload
1066             if (pEH->getArgs())
1067             {
1068                 // call overload
1069                 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1070
1071                 if ((*iterFields)->getExp() == NULL)
1072                 {
1073                     // a(x)(y)
1074                     // extract a(x) and push_BACK to extract next level
1075                     workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1076                     workFields.back()->setReinsertion();
1077                 }
1078                 else
1079                 {
1080                     // a(x).b
1081                     // extract a(x) and push_FRONT to extract b from a(x)
1082                     workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1083                     workFields.front()->setReinsertion();
1084                 }
1085             }
1086             else
1087             {
1088                 // a.x, get string "x"
1089                 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1090
1091                 // create arg with next field
1092                 typed_list* args = new typed_list();
1093                 args->push_back(new String(pwcsFieldname.c_str()));
1094                 pEH->setArgs(args);
1095
1096                 // call overload
1097                 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1098
1099                 // append extraction of a.x for next level.
1100                 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1101                 workFields.front()->setReinsertion();
1102             }
1103         }
1104         else if (pITCurrent->isCell())
1105         {
1106             Cell* pCell = pITCurrent->getAs<Cell>();
1107             if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
1108             {
1109                 if (pEH->isCellExp())
1110                 {
1111                     // a{x} => extract like a(x){[1 2 ...]}
1112                     if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
1113                     {
1114                         // extract each elements of a(x)
1115                         for (int iCell = 0; iCell < pCell->getSize(); iCell++)
1116                         {
1117                             InternalType* pIT = pCell->get(iCell);
1118                             if ((*iterFields)->getExp() == NULL)
1119                             {
1120                                 // a{x}(y)
1121                                 ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
1122                                 pEHChield->setWhereReinsert(iCell);
1123                                 workFields.push_back(pEHChield);
1124                             }
1125                             else
1126                             {
1127                                 // a{x}.b
1128                                 ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
1129                                 pEHChield->setWhereReinsert(iCell);
1130                                 workFields.push_front(pEHChield);
1131                             }
1132                         }
1133                     }
1134                     else
1135                     {
1136                         if (pEH->needResize())
1137                         {
1138                             if (pEH->getArgsDims() == 1)
1139                             {
1140                                 std::wostringstream os;
1141                                 os << _W("Invalid index.");
1142                                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1143                             }
1144
1145                             // resize current Cell
1146                             pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1147                         }
1148
1149                         InternalType* pIT = pCell->extract(pEH->getArgs());
1150                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
1151                         workFields.front()->setReinsertion();
1152                     }
1153                 }
1154                 else
1155                 {
1156                     if ((*iterFields)->isCellExp())
1157                     {
1158                         // a(x){y}
1159                         if (pEH->needResize())
1160                         {
1161                             if (pEH->getArgsDims() == 1)
1162                             {
1163                                 std::wostringstream os;
1164                                 os << _W("Invalid index.");
1165                                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1166                             }
1167
1168                             // resize current Cell
1169                             pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1170                         }
1171
1172                         InternalType* pIT = pCell->extract(pEH->getArgs());
1173                         workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
1174                         workFields.front()->setReinsertion();
1175                     }
1176                     else
1177                     {
1178                         // only a(x)
1179                         std::wostringstream os;
1180                         os << _W("Wrong insertion in a Cell.");
1181                         throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1182                     }
1183                 }
1184             }
1185             else
1186             {
1187                 std::wostringstream os;
1188                 os << _W("Wrong insertion in a Cell.");
1189                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1190             }
1191         }
1192         else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
1193         {
1194             // call userType extract method
1195             if (pEH->getArgs())
1196             {
1197                 // a(x)
1198                 InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(pEH->getArgs());
1199                 if (pExtract == NULL)
1200                 {
1201                     // call overload
1202                     pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1203                 }
1204
1205                 if ((*iterFields)->getExp() == NULL)
1206                 {
1207                     // a(x)(y)
1208                     // extract a(x) and push_BACK to extract next level
1209                     workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1210                     workFields.back()->setReinsertion();
1211                 }
1212                 else
1213                 {
1214                     // a(x).b
1215                     // extract a(x) and push_FRONT to extract b from a(x)
1216                     workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1217                     workFields.front()->setReinsertion();
1218                 }
1219             }
1220             else
1221             {
1222                 // a.x, get string "x"
1223                 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1224
1225                 // create arg with next field
1226                 typed_list* args = new typed_list();
1227                 args->push_back(new String(pwcsFieldname.c_str()));
1228                 pEH->setArgs(args);
1229
1230                 InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(args);
1231                 if (pExtract == NULL)
1232                 {
1233                     // call overload
1234                     pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1235                 }
1236
1237                 // append extraction of a.x for next level.
1238                 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1239                 workFields.front()->setReinsertion();
1240             }
1241         }
1242         else
1243         {
1244             InternalType* pIT = new Struct(1, 1);
1245             pEH->setCurrent(pIT);
1246             pEH->setReinsertion();
1247
1248             workFields.push_front(pEH);
1249             evalFields.pop_back();
1250         }
1251
1252         if (workFields.front()->getLevel() == (*iterFields)->getLevel())
1253         {
1254             // go to next field
1255             iterFields++;
1256         }
1257     }
1258
1259     //*** insert what we have to assign ***//
1260     while (workFields.empty() == false)
1261     {
1262         ExpHistory* pEH = workFields.front();
1263         evalFields.push_back(pEH);
1264         workFields.pop_front();
1265
1266         if (pEH->getArgs())
1267         {
1268             typed_list* pArgs = pEH->getArgs();
1269             if (pEH->isCellExp())
1270             {
1271                 Cell* pCell = pEH->getCurrent()->getAs<Cell>();
1272                 // insert "something" in b{x}
1273                 if ((*pArgs)[0]->isString())
1274                 {
1275                     std::wostringstream os;
1276                     os << _W("Wrong insertion in a Cell.");
1277                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1278                 }
1279
1280                 pCell->insertCell(pArgs, _pAssignValue);
1281             }
1282             else
1283             {
1284                 // insert "something" in b(x,y)
1285                 InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
1286                 if (pIT == NULL)
1287                 {
1288                     std::wostringstream os;
1289                     os << _W("Submatrix incorrectly defined.");
1290                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1291                 }
1292
1293                 if (pEH->setCurrent(pIT))
1294                 {
1295                     pEH->setReinsertion();
1296                 }
1297             }
1298         }
1299         else
1300         {
1301             InternalType* pParent = pEH->getParent()->getCurrent();
1302             if (pParent->isStruct())
1303             {
1304                 Struct* pStruct = pParent->getAs<Struct>();
1305                 if (_pAssignValue->isListDelete())
1306                 {
1307                     pStruct->removeField(pEH->getExpAsString());
1308                 }
1309                 else
1310                 {
1311                     pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), _pAssignValue);
1312                 }
1313
1314                 // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
1315                 delete pEH;
1316                 evalFields.pop_back();
1317             }
1318             else if (pParent->isTList() || pParent->isMList())
1319             {
1320                 TList* pTL = pParent->getAs<TList>();
1321                 if (_pAssignValue->isListDelete() || (pTL->exists(pEH->getExpAsString()) == false))
1322                 {
1323                     typed_list args;
1324                     args.push_back(new String(pEH->getExpAsString().c_str()));
1325                     InternalType* pIT = insertionCall(*_pExp, &args, pEH->getParent()->getCurrent(), _pAssignValue);
1326                     if (pIT == NULL)
1327                     {
1328                         std::wostringstream os;
1329                         os << _W("Error in insertion of TList.");
1330                         throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1331                     }
1332
1333                     if (pEH->getParent()->setCurrent(pIT))
1334                     {
1335                         pEH->getParent()->setReinsertion();
1336                         pEH->resetReinsertion();
1337                     }
1338                 }
1339                 else
1340                 {
1341                     pTL->set(pEH->getExpAsString(), _pAssignValue);
1342                 }
1343
1344                 // set _pAssignValue in parent, so kill the current if needed
1345                 // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
1346                 delete pEH;
1347                 evalFields.pop_back();
1348             }
1349             else
1350             {
1351                 pEH->setCurrent(_pAssignValue);
1352                 pEH->setReinsertion();
1353             }
1354         }
1355     }
1356
1357     //*** update fields ***//
1358     while (evalFields.empty() == false)
1359     {
1360         ExpHistory* pEH = evalFields.back();
1361         if (pEH->reinsertMe())
1362         {
1363             ExpHistory* pEHParent = pEH->getParent();
1364
1365             if (pEHParent == NULL)
1366             {
1367                 symbol::Context::getInstance()->put(pEH->getExp()->getStack(), pEH->getCurrent());
1368                 break;
1369             }
1370
1371             typed_list* pParentArgs = pEHParent->getArgs();
1372             if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
1373             {
1374                 InternalType* pParent = pEHParent->getCurrent();
1375                 if (pParent->isStruct())
1376                 {
1377                     Struct* pStruct = pParent->getAs<Struct>();
1378                     pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
1379                     evalFields.pop_back();
1380                     delete pEH;
1381                     continue;
1382                 }
1383                 else if (pParent->isTList() || pParent->isMList())
1384                 {
1385                     TList* pTL = pParent->getAs<TList>();
1386                     if (pParentArgs)
1387                     {
1388                         pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
1389                         evalFields.pop_back();
1390                         delete pEH;
1391                         continue;
1392                     }
1393                     else
1394                     {
1395                         if (pTL->exists(pEH->getExpAsString()))
1396                         {
1397                             pTL->set(pEH->getExpAsString(), pEH->getCurrent());
1398                             evalFields.pop_back();
1399                             delete pEH;
1400                             continue;
1401                         }
1402
1403                         pParentArgs = new typed_list();
1404                         pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
1405                     }
1406                 }
1407                 else if (pParent->isCell())
1408                 {
1409                     Cell* pCell = pParent->getAs<Cell>();
1410                     if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
1411                     {
1412                         // a{x}.b => reinsert b in a{x}
1413                         pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
1414                         pEHParent->setReinsertion();
1415                         evalFields.pop_back();
1416                         delete pEH;
1417                         continue;
1418                     }
1419                 }
1420             }
1421
1422             InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
1423             if (pIT == NULL)
1424             {
1425                 std::wostringstream os;
1426                 os << _W("Submatrix incorrectly defined.");
1427                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1428             }
1429
1430             if (pEHParent->setCurrent(pIT))
1431             {
1432                 pEHParent->setReinsertion();
1433             }
1434
1435             if (pEHParent->getArgs() == NULL)
1436             {
1437                 delete pParentArgs;
1438             }
1439         }
1440
1441         if (pEH->getCurrent())
1442         {
1443             pEH->getCurrent()->killMe();
1444         }
1445
1446         evalFields.pop_back();
1447         delete pEH;
1448     }
1449
1450     if (!evalFields.empty())
1451     {
1452         for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
1453         {
1454             delete *i;
1455         }
1456     }
1457
1458     return symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
1459 }
1460
1461 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
1462 {
1463     InternalType* pOut = NULL;
1464     InternalType *pIL = NULL;
1465     //fisrt extract implicit list
1466     if (_pInsert->isColon())
1467     {
1468         //double* pdbl = NULL;
1469         //_pInsert = new Double(-1, -1, &pdbl);
1470         //pdbl[0] = 1;
1471         pIL = Double::Identity(-1, -1);
1472         _pInsert->killMe();
1473         _pInsert = pIL;
1474     }
1475     else if (_pInsert->isImplicitList())
1476     {
1477         pIL = _pInsert->getAs<ImplicitList>()->extractFullMatrix();
1478         if (pIL && pIL->isDeletable())
1479         {
1480             _pInsert->killMe();
1481             _pInsert = pIL;
1482         }
1483     }
1484     else if (_pInsert->isContainer() && _pInsert->isRef())
1485     {
1486         //std::cout << "assign container type during insertion" << std::endl;
1487         //InternalType* pIL = _pInsert->clone();
1488         //_pInsert = pIL;
1489     }
1490
1491     if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar == NULL)
1492     {
1493         // l(x) = [] when l is not defined => create l = []
1494         pOut = Double::Empty();
1495     }
1496     else if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1497     {
1498         //insert [] so deletion except for Struct and List which can insert []
1499         InternalType::ScilabType varType = _pVar->getType();
1500         switch (varType)
1501         {
1502             case InternalType::ScilabDouble :
1503             {
1504                 pOut = _pVar->getAs<Double>()->remove(_pArgs);
1505                 break;
1506             }
1507             case InternalType::ScilabString :
1508             {
1509                 pOut = _pVar->getAs<String>()->remove(_pArgs);
1510                 break;
1511             }
1512             case InternalType::ScilabCell :
1513             {
1514                 pOut = _pVar->getAs<Cell>()->remove(_pArgs);
1515                 break;
1516             }
1517             case InternalType::ScilabBool :
1518             {
1519                 pOut = _pVar->getAs<Bool>()->remove(_pArgs);
1520                 break;
1521             }
1522             case InternalType::ScilabPolynom :
1523             {
1524                 pOut = _pVar->getAs<Polynom>()->remove(_pArgs);
1525                 break;
1526             }
1527             case InternalType::ScilabInt8 :
1528             {
1529                 pOut = _pVar->getAs<Int8>()->remove(_pArgs);
1530                 break;
1531             }
1532             case InternalType::ScilabUInt8 :
1533             {
1534                 pOut = _pVar->getAs<UInt8>()->remove(_pArgs);
1535                 break;
1536             }
1537             case InternalType::ScilabInt16 :
1538             {
1539                 pOut = _pVar->getAs<Int16>()->remove(_pArgs);
1540                 break;
1541             }
1542             case InternalType::ScilabUInt16 :
1543             {
1544                 pOut = _pVar->getAs<UInt16>()->remove(_pArgs);
1545                 break;
1546             }
1547             case InternalType::ScilabInt32 :
1548             {
1549                 pOut = _pVar->getAs<Int32>()->remove(_pArgs);
1550                 break;
1551             }
1552             case InternalType::ScilabUInt32 :
1553             {
1554                 pOut = _pVar->getAs<UInt32>()->remove(_pArgs);
1555                 break;
1556             }
1557             case InternalType::ScilabInt64 :
1558             {
1559                 pOut = _pVar->getAs<Int64>()->remove(_pArgs);
1560                 break;
1561             }
1562             case InternalType::ScilabUInt64 :
1563             {
1564                 pOut = _pVar->getAs<UInt64>()->remove(_pArgs);
1565                 break;
1566             }
1567             case InternalType::ScilabSparse :
1568             {
1569                 pOut = _pVar->getAs<Sparse>()->remove(_pArgs);
1570                 break;
1571             }
1572             case InternalType::ScilabSparseBool :
1573             {
1574                 pOut = _pVar->getAs<SparseBool>()->remove(_pArgs);
1575                 break;
1576             }
1577             case InternalType::ScilabStruct :
1578             {
1579                 pOut = _pVar->getAs<Struct>()->insert(_pArgs, _pInsert);
1580                 break;
1581             }
1582             case InternalType::ScilabHandle :
1583             {
1584                 types::GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
1585                 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1586
1587                 typed_list in;
1588                 typed_list out;
1589                 optional_list opt;
1590                 ast::ExecVisitor exec;
1591
1592                 in.push_back(pH);
1593                 in.push_back(pS);
1594                 in.push_back(_pInsert);
1595
1596                 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1597                 Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, &exec);
1598                 if (ret == Callable::OK)
1599                 {
1600                     pOut = _pVar;
1601                 }
1602                 break;
1603             }
1604             default :
1605             {
1606                 //overload !
1607                 pOut = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1608                 break;
1609             }
1610         }
1611     }
1612     else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<Double>()->getSize() == 0))
1613     {
1614         //insert in a new variable or []
1615         //call static insert function
1616         //if _pVar == NULL and pArg is single string, it's a struct creation
1617         if ((*_pArgs)[0]->isString())
1618         {
1619             String *pS = (*_pArgs)[0]->getAs<types::String>();
1620             Struct* pStr = new Struct(1, 1);
1621
1622             if (_pArgs->size() != 1 || pS->isScalar() == false)
1623             {
1624                 if (pIL)
1625                 {
1626                     pIL->killMe();
1627                 }
1628                 //manage error
1629                 std::wostringstream os;
1630                 os << _W("Invalid Index.\n");
1631                 throw ast::ScilabError(os.str(), 999, e.getLocation());
1632             }
1633
1634             pStr->addField(pS->get(0));
1635             pStr->get(0)->set(pS->get(0), _pInsert);
1636             pOut = pStr;
1637         }
1638         else
1639         {
1640             switch (_pInsert->getType())
1641             {
1642                 case InternalType::ScilabDouble :
1643                     pOut = Double::insertNew(_pArgs, _pInsert);
1644                     break;
1645                 case InternalType::ScilabString :
1646                     pOut = String::insertNew(_pArgs, _pInsert);
1647                     break;
1648                 case InternalType::ScilabCell :
1649                     pOut = Cell::insertNew(_pArgs, _pInsert);
1650                     break;
1651                 case InternalType::ScilabBool :
1652                     pOut = Bool::insertNew(_pArgs, _pInsert);
1653                     break;
1654                 case InternalType::ScilabPolynom :
1655                     pOut = Polynom::insertNew(_pArgs, _pInsert);
1656                     break;
1657                 case InternalType::ScilabInt8 :
1658                     pOut = Int8::insertNew(_pArgs, _pInsert);
1659                     break;
1660                 case InternalType::ScilabUInt8 :
1661                     pOut = UInt8::insertNew(_pArgs, _pInsert);
1662                     break;
1663                 case InternalType::ScilabInt16 :
1664                     pOut = Int16::insertNew(_pArgs, _pInsert);
1665                     break;
1666                 case InternalType::ScilabUInt16 :
1667                     pOut = UInt16::insertNew(_pArgs, _pInsert);
1668                     break;
1669                 case InternalType::ScilabInt32 :
1670                     pOut = Int32::insertNew(_pArgs, _pInsert);
1671                     break;
1672                 case InternalType::ScilabUInt32 :
1673                     pOut = UInt32::insertNew(_pArgs, _pInsert);
1674                     break;
1675                 case InternalType::ScilabInt64 :
1676                     pOut = Int64::insertNew(_pArgs, _pInsert);
1677                     break;
1678                 case InternalType::ScilabUInt64 :
1679                     pOut = UInt64::insertNew(_pArgs, _pInsert);
1680                     break;
1681                 case InternalType::ScilabSparse :
1682                     pOut = Sparse::insertNew(_pArgs, _pInsert);
1683                     break;
1684                 case InternalType::ScilabSparseBool :
1685                     pOut = SparseBool::insertNew(_pArgs, _pInsert);
1686                     break;
1687                 case InternalType::ScilabHandle:
1688                     pOut = GraphicHandle::insertNew(_pArgs, _pInsert);
1689                     break;
1690                 default :
1691                 {
1692                     // overload
1693                     types::Double* pEmpty = types::Double::Empty();
1694                     pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1695                     pEmpty->killMe();
1696                     break;
1697                 }
1698             }
1699         }
1700     }
1701     else
1702     {
1703         //call type insert function
1704         InternalType* pRet = NULL;
1705
1706         //check types compatibilties
1707         if (_pVar->isDouble() && _pInsert->isDouble())
1708         {
1709             pRet = _pVar->getAs<Double>()->insert(_pArgs, _pInsert);
1710         }
1711         else if (_pVar->isDouble() && _pInsert->isSparse())
1712         {
1713             Sparse* pSp = _pInsert->getAs<Sparse>();
1714             Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1715             pSp->fill(*pD);
1716             pRet = _pVar->getAs<Double>()->insert(_pArgs, pD);
1717             free(pD);
1718         }
1719         else if (_pVar->isString() && _pInsert->isString())
1720         {
1721             pRet = _pVar->getAs<String>()->insert(_pArgs, _pInsert);
1722         }
1723         else if (_pVar->isCell() && _pInsert->isCell())
1724         {
1725             pRet = _pVar->getAs<Cell>()->insert(_pArgs, _pInsert);
1726         }
1727         else if (_pVar->isBool() && _pInsert->isBool())
1728         {
1729             pRet = _pVar->getAs<Bool>()->insert(_pArgs, _pInsert);
1730         }
1731         else if (_pVar->isSparse() && _pInsert->isSparse())
1732         {
1733             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert->getAs<Sparse>());
1734         }
1735         else if (_pVar->isSparse() && _pInsert->isDouble())
1736         {
1737             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert);
1738         }
1739         else if (_pVar->isSparseBool() && _pInsert->isSparseBool())
1740         {
1741             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert->getAs<SparseBool>());
1742         }
1743         else if (_pVar->isSparseBool() && _pInsert->isBool())
1744         {
1745             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert);
1746         }
1747         else if (_pVar->isDouble() && _pInsert->isPoly())
1748         {
1749             Double* pDest = _pVar->getAs<Double>();
1750             Polynom* pIns = _pInsert->getAs<Polynom>();
1751             int iSize = pDest->getSize();
1752             int* piRanks = new int[iSize];
1753             memset(piRanks, 0x00, iSize * sizeof(int));
1754             Polynom* pP = new Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1755             delete[] piRanks;
1756             pP->setComplex(pDest->isComplex());
1757
1758             if (pP->isComplex())
1759             {
1760                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1761                 {
1762                     double dblR = pDest->get(idx);
1763                     double dblI = pDest->getImg(idx);
1764                     pP->get(idx)->setCoef(&dblR, &dblI);
1765                 }
1766             }
1767             else
1768             {
1769                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1770                 {
1771                     double dblR = pDest->get(idx);
1772                     pP->get(idx)->setCoef(&dblR, NULL);
1773                 }
1774             }
1775
1776             pRet = pP->insert(_pArgs, pIns);
1777             pDest->DecreaseRef();
1778         }
1779         else if (_pVar->isPoly() && _pInsert->isDouble())
1780         {
1781             Polynom* pDest = _pVar->getAs<Polynom>();
1782             Double* pIns = _pInsert->getAs<Double>();
1783             bool isComplexIns = pIns->isComplex();
1784             int iSize = pIns->getSize();
1785             int* piRanks = new int[iSize];
1786             memset(piRanks, 0x00, iSize * sizeof(int));
1787
1788             //create a new polynom with Double to insert it into dest polynom
1789             Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
1790             delete[] piRanks;
1791
1792             if (isComplexIns)
1793             {
1794                 double* pR = pIns->get();
1795                 double* pI = pIns->getImg();
1796                 SinglePoly** pSP = pP->get();
1797                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1798                 {
1799                     double dblR = pR[idx];
1800                     double dblI = pI[idx];
1801                     pSP[idx]->setComplex(true);
1802                     pSP[idx]->setCoef(&dblR, &dblI);
1803                 }
1804             }
1805             else
1806             {
1807                 double* pdblR = pIns->get();
1808                 SinglePoly** pSP = pP->get();
1809                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1810                 {
1811                     double dblR = pdblR[idx];
1812                     pSP[idx]->setCoef(&dblR, NULL);
1813                 }
1814             }
1815
1816             pRet = pDest->insert(_pArgs, pP);
1817             pP->killMe();
1818         }
1819         else if (_pVar->isPoly() && _pInsert->isPoly())
1820         {
1821             pRet = _pVar->getAs<Polynom>()->insert(_pArgs, _pInsert);
1822         }
1823         else if (_pVar->isInt8() && _pInsert->isInt8())
1824         {
1825             pRet = _pVar->getAs<Int8>()->insert(_pArgs, _pInsert);
1826         }
1827         else if (_pVar->isUInt8() && _pInsert->isUInt8())
1828         {
1829             pRet = _pVar->getAs<UInt8>()->insert(_pArgs, _pInsert);
1830         }
1831         else if (_pVar->isInt16() && _pInsert->isInt16())
1832         {
1833             pRet = _pVar->getAs<Int16>()->insert(_pArgs, _pInsert);
1834         }
1835         else if (_pVar->isUInt16() && _pInsert->isUInt16())
1836         {
1837             pRet = _pVar->getAs<UInt16>()->insert(_pArgs, _pInsert);
1838         }
1839         else if (_pVar->isInt32() && _pInsert->isInt32())
1840         {
1841             pRet = _pVar->getAs<Int32>()->insert(_pArgs, _pInsert);
1842         }
1843         else if (_pVar->isUInt32() && _pInsert->isUInt32())
1844         {
1845             pRet = _pVar->getAs<UInt32>()->insert(_pArgs, _pInsert);
1846         }
1847         else if (_pVar->isInt64() && _pInsert->isInt64())
1848         {
1849             pRet = _pVar->getAs<Int64>()->insert(_pArgs, _pInsert);
1850         }
1851         else if (_pVar->isUInt64() && _pInsert->isUInt64())
1852         {
1853             pRet = _pVar->getAs<UInt64>()->insert(_pArgs, _pInsert);
1854         }
1855         else if (_pVar->isStruct())
1856         {
1857             Struct* pStruct = _pVar->getAs<Struct>();
1858             // insert something in a field of a struct
1859             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
1860             {
1861                 //s("x") = y
1862                 String *pS = (*_pArgs)[0]->getAs<types::String>();
1863                 if (pS->isScalar() == false)
1864                 {
1865                     if (pIL)
1866                     {
1867                         pIL->killMe();
1868                     }
1869                     //manage error
1870                     std::wostringstream os;
1871                     os << _W("Invalid Index.\n");
1872                     throw ast::ScilabError(os.str(), 999, e.getLocation());
1873                 }
1874
1875                 pStruct->addField(pS->get(0));
1876                 for (int i = 0; i < pStruct->getSize(); i++)
1877                 {
1878                     pStruct->get(i)->set(pS->get(0), _pInsert);
1879                 }
1880
1881                 pRet = pStruct;
1882             }
1883             else // insert something in a struct
1884             {
1885                 if (_pInsert->isStruct())
1886                 {
1887                     String* pStrFieldsName = pStruct->getFieldNames();
1888                     Struct* pStructInsert = _pInsert->clone()->getAs<Struct>();
1889                     String* pStrInsertFieldsName = pStructInsert->getFieldNames();
1890                     Struct* pStructRet = NULL;
1891
1892                     // if not an empty struct
1893                     if (pStrFieldsName)
1894                     {
1895                         // insert fields of pStruct in pStructInsert
1896                         for (int i = pStrFieldsName->getSize(); i > 0; i--)
1897                         {
1898                             if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
1899                             {
1900                                 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
1901                             }
1902                             else
1903                             {
1904                                 std::wstring pwcsField = pStrFieldsName->get(i - 1);
1905                                 List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
1906
1907                                 for (int i = 0; i < pLExtract->getSize(); i++)
1908                                 {
1909                                     // protect element wich are not cloned before call removeField.
1910                                     pLExtract->get(i)->IncreaseRef();
1911                                 }
1912
1913                                 pStructInsert->removeField(pwcsField);
1914                                 pStructInsert->addFieldFront(pwcsField);
1915
1916                                 for (int i = 0; i < pLExtract->getSize(); i++)
1917                                 {
1918                                     // set elements in the new position
1919                                     pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
1920                                 }
1921
1922                                 pLExtract->killMe();
1923                             }
1924                         }
1925
1926                         pStrFieldsName->killMe();
1927                     }
1928
1929                     // insert elements in following pArgs
1930                     pRet = pStruct->insert(_pArgs, pStructInsert);
1931                     pStructRet = pRet->getAs<Struct>();
1932
1933                     pStructInsert->killMe();
1934
1935                     // insert fields of pStructInsert in pRet
1936                     for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
1937                     {
1938                         if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
1939                         {
1940                             pStructRet->addField(pStrInsertFieldsName->get(i));
1941                         }
1942                     }
1943
1944                     pStrInsertFieldsName->killMe();
1945                 }
1946                 else
1947                 {
1948                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1949                 }
1950             }
1951         }
1952         else if (_pVar->isTList() || _pVar->isMList())
1953         {
1954             TList* pTL = _pVar->getAs<TList>();
1955             if (_pArgs->size() == 1)
1956             {
1957                 if ((*_pArgs)[0]->isString())
1958                 {
1959                     //s("x") = y
1960                     String *pS = (*_pArgs)[0]->getAs<types::String>();
1961                     if (pS->isScalar() == false)
1962                     {
1963                         if (pIL)
1964                         {
1965                             pIL->killMe();
1966                         }
1967
1968                         //manage error
1969                         std::wostringstream os;
1970                         os << _W("Invalid Index.\n");
1971                         throw ast::ScilabError(os.str(), 999, e.getLocation());
1972                     }
1973
1974                     if (_pInsert->isListDelete())
1975                     {
1976                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1977                     }
1978
1979                     if (pTL->exists(pS->get(0)))
1980                     {
1981                         pTL->set(pS->get(0), _pInsert);
1982                         pRet = pTL;
1983                     }
1984                     else
1985                     {
1986                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1987
1988                         //ExecVisitor exec;
1989                         //types::typed_list in;
1990                         //types::typed_list out;
1991                         //std::wstring function_name = L"%l_e";
1992
1993                         //_pInsert->IncreaseRef();
1994                         //in.push_back(_pInsert);
1995
1996                         //Overload::call(function_name, in, 1, out, &exec);
1997                         //_pInsert->DecreaseRef();
1998
1999                         //if (out.size() != 0)
2000                         //{
2001                         //    pRet = in[0];
2002                         //}
2003                     }
2004                 }
2005                 else
2006                 {
2007                     // s(x)
2008                     if (_pVar->isMList())
2009                     {
2010                         pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2011                     }
2012                     else
2013                     {
2014                         pRet = pTL->insert(_pArgs, _pInsert);
2015                     }
2016                 }
2017             }
2018             else
2019             {
2020                 if (_pVar->isMList())
2021                 {
2022                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2023                 }
2024                 else
2025                 {
2026                     // call the overload if it exists.
2027                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2028                     if (pRet == NULL)
2029                     {
2030                         // else normal insert
2031                         pRet = pTL->insert(_pArgs, _pInsert);
2032                     }
2033                 }
2034             }
2035         }
2036         else if (_pVar->isList())
2037         {
2038             pRet = _pVar->getAs<List>()->insert(_pArgs, _pInsert);
2039             if (pRet == NULL)
2040             {
2041                 // call overload
2042                 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2043             }
2044         }
2045         else if (_pVar->isHandle())
2046         {
2047             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2048             {
2049                 //s(["x"])
2050                 types::GraphicHandle* pH = _pVar->getAs<types::GraphicHandle>();
2051                 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
2052                 typed_list in;
2053                 typed_list out;
2054                 optional_list opt;
2055                 ast::ExecVisitor exec;
2056
2057                 in.push_back(pH);
2058                 in.push_back(pS);
2059                 in.push_back(_pInsert);
2060
2061                 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2062                 if (pCall)
2063                 {
2064                     Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
2065                     if (ret == Callable::OK)
2066                     {
2067                         pRet = _pVar;
2068                     }
2069                 }
2070             }
2071             else
2072             {
2073                 pRet = _pVar->getAs<types::GraphicHandle>()->insert(_pArgs, _pInsert);
2074             }
2075         }
2076         else if (_pVar->isUserType())
2077         {
2078             pRet = _pVar->getAs<types::UserType>()->insert(_pArgs, _pInsert);
2079             if (pRet == NULL)
2080             {
2081                 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2082             }
2083         }
2084         else
2085         {
2086             // overload
2087             pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2088         }
2089
2090         pOut = pRet;
2091     }
2092
2093     if (pIL)
2094     {
2095         pIL->killMe();
2096     }
2097
2098     return pOut;
2099 }
2100
2101 void callOnPrompt(void)
2102 {
2103     static symbol::Variable* onPrompt = NULL;
2104
2105     if (onPrompt == NULL)
2106     {
2107         onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2108     }
2109
2110     types::InternalType* pOnPrompt = NULL;
2111     pOnPrompt = onPrompt->get();
2112     if (pOnPrompt != NULL && pOnPrompt->isCallable())
2113     {
2114         types::typed_list in;
2115         types::typed_list out;
2116         types::optional_list opt;
2117         ast::ExecVisitor execCall;
2118         pOnPrompt->getAs<types::Callable>()->call(in, opt, 1, out, &execCall);
2119     }
2120 }
2121
2122 List* getPropertyTree(ast::Exp* e, List* pList)
2123 {
2124
2125     //a.b
2126     ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(e);
2127     if (pVar)
2128     {
2129         pList->append(new String(pVar->getSymbol().getName().c_str()));
2130         return pList;
2131     }
2132
2133     //a(x).b
2134     ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(e);
2135     if (pCall)
2136     {
2137         pList = getPropertyTree(&pCall->getName(), pList);
2138         ast::ExecVisitor exec;
2139         ast::exps_t l = pCall->getArgs();
2140         ast::exps_t::const_iterator it;
2141         for (ast::exps_t::const_iterator it = l.begin(), itEnd = l.end() ; it != itEnd ; ++it)
2142         {
2143             try
2144             {
2145                 (*it)->accept(exec);
2146                 pList->append(exec.getResult());
2147                 exec.clearResult();
2148             }
2149             catch (ast::ScilabException e)
2150             {
2151                 throw e;
2152             }
2153         }
2154
2155         return pList;
2156     }
2157
2158     //a.b.c
2159     ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(e);
2160     if (pField)
2161     {
2162         pList = getPropertyTree(pField->getHead(), pList);
2163         pList = getPropertyTree(pField->getTail(), pList);
2164         return pList;
2165     }
2166
2167     return pList;
2168 }
2169
2170 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2171 {
2172     ast::Exp* newTree = NULL;
2173     unsigned char *newast = NULL;
2174     ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2175     ast::DeserializeVisitor* d = NULL;
2176
2177     if (_msg.empty())
2178     {
2179         unsigned char* astbin = s->serialize();
2180         //call ocamlpro typer
2181         //char *newast = ocamlpro_typer(astbin);
2182         //free(astbin);
2183
2184         //for debug
2185         newast = astbin;
2186
2187         d = new ast::DeserializeVisitor(newast);
2188         newTree = d->deserialize();
2189     }
2190     else
2191     {
2192         std::wstring msgS(_msg + L" serialize");
2193         std::wstring msgD(_msg + L" deserialize");
2194
2195         Timer timer;
2196         timer.start();
2197         unsigned char* astbin = s->serialize();
2198         timer.check(msgS.c_str());
2199
2200         //call ocamlpro typer
2201         //char *newast = ocamlpro_typer(astbin);
2202         //free(astbin);
2203
2204         //for debug
2205         newast = astbin;
2206
2207         timer.start();
2208         d = new ast::DeserializeVisitor(newast);
2209         newTree = d->deserialize();
2210         timer.check(msgD.c_str());
2211     }
2212
2213     free(newast);
2214     delete s;
2215     delete d;
2216     return newTree;
2217 }