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