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