somes modifications about UserType
[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                             pList->killMe();
1025                             std::wostringstream os;
1026                             os << _W("Unable to insert multiple item in a List.");
1027                             throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1028                         }
1029
1030                         double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
1031                         if ((*iterFields)->getExp() == NULL)
1032                         {
1033                             // a(x)(y)
1034                             // extract a(x) and push_BACK to extract y
1035                             ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(0));
1036                             pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
1037                             workFields.push_back(pEHExtract);
1038                         }
1039                         else
1040                         {
1041                             // a(x).b
1042                             // extract a(x) and push_FRONT to extract b
1043                             ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(0));
1044                             pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
1045                             workFields.push_front(pEHExtract);
1046                         }
1047
1048                         //extract create a list to store items
1049                         pList->killMe();
1050                     }
1051                 }
1052                 else
1053                 {
1054                     // get string "x" of a.x
1055                     InternalType* pExtract = NULL;
1056                     std::wstring pwcsFieldname = L"";
1057                     bool bReinsert = false;
1058                     ExpHistory* pEHChield = NULL;
1059
1060                     pwcsFieldname = (*iterFields)->getExpAsString();
1061
1062                     // check if the field x is the last field
1063                     std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1064                     ++iterFieldsNext;
1065                     if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1066                     {
1067                         // create pArg with "x" and set it as argument of "a"
1068                         typed_list* args = new typed_list();
1069                         args->push_back(new String(pwcsFieldname.c_str()));
1070                         pEH->setArgs(args);
1071
1072                         // a.x where x is the last field
1073                         // insert directly in x instead of extract then insert
1074                         ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1075                         pEHNext->setReinsertion();
1076                         evalFields.push_back(pEHNext);
1077                         if (workFields.empty())
1078                         {
1079                             break;
1080                         }
1081                     }
1082                     else
1083                     {
1084                         // check if field exists
1085                         if (pTL->exists(pwcsFieldname) == false)
1086                         {
1087                             std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1088                             ++iterFieldsNext;
1089
1090                             if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
1091                             {
1092                                 // M=mlist(['MType','x','y'], ...
1093                                 // M.rows1 = "somthing"
1094                                 pArgs = new typed_list();
1095                                 pArgs->push_back(new String(pwcsFieldname.c_str()));
1096
1097                                 // call overload
1098                                 pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
1099                                 bReinsert = true;
1100
1101                                 delete pArgs;
1102                             }
1103                         }
1104                         else
1105                         {
1106                             // extract field x and append it to elements for next recursion.
1107                             pExtract = pTL->getField(pwcsFieldname);
1108                         }
1109
1110                         pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
1111                         workFields.push_back(pEHChield);
1112
1113                         if (bReinsert)
1114                         {
1115                             pEHChield->setReinsertion();
1116                         }
1117                     }
1118                 }
1119             }
1120             else if (pITCurrent->isList())
1121             {
1122                 List* pL = pITCurrent->getAs<List>();
1123                 if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
1124                 {
1125                     std::wostringstream os;
1126                     os << _W("Wrong insertion.");
1127                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1128
1129                     //                    // pITCurrent is an extraction of other Type
1130                     //                    for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
1131                     //                    {
1132                     //                        ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
1133                     //                        pEHExtract->setWhereReinsert(iLoop);
1134                     //                        workFields.push_front(pEHExtract);
1135                     //                    }
1136                 }
1137                 else
1138                 {
1139                     // pITCurrent is a field
1140                     if (pEH->getArgs())
1141                     {
1142                         if (pEH->getArgs()->size() > 1)
1143                         {
1144                             // call overload
1145                             InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
1146
1147                             if ((*iterFields)->getExp() == NULL)
1148                             {
1149                                 // a(x)(y)
1150                                 // extract a(x) and push_BACK to extract next level
1151                                 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1152                                 workFields.back()->setReinsertion();
1153                             }
1154                             else
1155                             {
1156                                 // a(x).b
1157                                 // extract a(x) and push_FRONT to extract b from a(x)
1158                                 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1159                                 workFields.front()->setReinsertion();
1160                             }
1161                         }
1162                         else
1163                         {
1164                             // resize List
1165                             int iNewSize = pEH->getSizeFromArgs();
1166                             if (pL->getSize() < iNewSize)
1167                             {
1168                                 pL->set(iNewSize - 1, new ListUndefined());
1169                             }
1170
1171                             Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
1172                             double* pdblArgs = pDblArgs->get();
1173
1174                             if ((*iterFields)->getExp() == NULL)
1175                             {
1176                                 // a(x)(y) => a.b(y)
1177                                 // extract a(x) and push_BACK to extract next level
1178                                 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1179                                 {
1180                                     ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1181                                     pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1182                                     workFields.push_back(pEHExtract);
1183                                 }
1184                             }
1185                             else
1186                             {
1187                                 // a(x).b
1188                                 // extract a(x) and push_FRONT to extract b from a(x)
1189                                 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1190                                 {
1191                                     ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1192                                     pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1193                                     workFields.push_front(pEHExtract);
1194                                 }
1195                             }
1196                         }
1197                     }
1198                     else
1199                     {
1200                         // a.x, get string "x"
1201                         std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1202
1203                         // create pArg with "x"
1204                         typed_list* args = new typed_list();
1205                         args->push_back(new String(pwcsFieldname.c_str()));
1206                         pEH->setArgs(args);
1207
1208                         // check if the field x is the last field
1209                         std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1210                         ++iterFieldsNext;
1211                         if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1212                         {
1213                             // a.x where x is the last field
1214                             // insert directly in x instead of extract then insert
1215                             ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1216                             pEHNext->setReinsertion();
1217                             evalFields.push_back(pEHNext);
1218                             if (workFields.empty())
1219                             {
1220                                 break;
1221                             }
1222                         }
1223                         else
1224                         {
1225                             // call overload
1226                             InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
1227
1228                             // append extraction of a.x for next level.
1229                             workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1230                             workFields.back()->setReinsertion();
1231                         }
1232                     }
1233                 }
1234             }
1235             else if (pITCurrent->isHandle())
1236             {
1237                 typed_list* pArgs = pEH->getArgs();
1238                 GraphicHandle* pGH = pITCurrent->getAs<GraphicHandle>();
1239                 if (pArgs)
1240                 {
1241                     InternalType* pExtract = NULL;
1242
1243                     for (int i = 0; i < pArgs->size(); i++)
1244                     {
1245                         if ((*pArgs)[i]->isImplicitList())
1246                         {
1247                             pExtract = pGH->extract(pArgs);
1248                             break;
1249                         }
1250                     }
1251
1252                     if (pExtract == NULL)
1253                     {
1254                         // call overload
1255                         pExtract = callOverload(*pEH->getExp(), L"e", pArgs, pITCurrent, NULL);
1256                     }
1257
1258                     if ((*iterFields)->getExp() == NULL)
1259                     {
1260                         // a(x)(y)
1261                         // extract a(x) and push_BACK to extract next level
1262                         workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1263                         workFields.back()->setReinsertion();
1264                     }
1265                     else
1266                     {
1267                         // a(x).b
1268                         // extract a(x) and push_FRONT to extract b from a(x)
1269                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1270                         workFields.front()->setReinsertion();
1271                     }
1272                 }
1273                 else
1274                 {
1275                     // a.x, get string "x"
1276                     std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1277
1278                     // create arg with next field
1279                     typed_list* args = new typed_list();
1280                     args->push_back(new String(pwcsFieldname.c_str()));
1281                     pEH->setArgs(args);
1282
1283                     // check if the field x is the last field
1284                     std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1285                     ++iterFieldsNext;
1286                     if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1287                     {
1288                         // a.x where x is the last field
1289                         // insert directly in x instead of extract then insert
1290                         ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1291                         pEHNext->setReinsertion();
1292                         evalFields.push_back(pEHNext);
1293                         if (workFields.empty())
1294                         {
1295                             break;
1296                         }
1297                     }
1298                     else
1299                     {
1300                         // call overload
1301                         InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1302
1303                         // append extraction of a.x for next level.
1304                         workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1305                         workFields.front()->setReinsertion();
1306                     }
1307                 }
1308             }
1309             else if (pITCurrent->isCell())
1310             {
1311                 Cell* pCell = pITCurrent->getAs<Cell>();
1312                 if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
1313                 {
1314                     if (pEH->isCellExp())
1315                     {
1316                         // a{x} => extract like a(x){[1 2 ...]}
1317                         if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
1318                         {
1319                             // extract each elements of a(x)
1320                             for (int iCell = 0; iCell < pCell->getSize(); iCell++)
1321                             {
1322                                 InternalType* pIT = pCell->get(iCell);
1323                                 if ((*iterFields)->getExp() == NULL)
1324                                 {
1325                                     // a{x}(y)
1326                                     ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
1327                                     pEHChield->setWhereReinsert(iCell);
1328                                     workFields.push_back(pEHChield);
1329                                 }
1330                                 else
1331                                 {
1332                                     // a{x}.b
1333                                     ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
1334                                     pEHChield->setWhereReinsert(iCell);
1335                                     workFields.push_front(pEHChield);
1336                                 }
1337                             }
1338                         }
1339                         else
1340                         {
1341                             if (pEH->needResize())
1342                             {
1343                                 if (pEH->getArgsDims() == 1)
1344                                 {
1345                                     std::wostringstream os;
1346                                     os << _W("Invalid index.");
1347                                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1348                                 }
1349
1350                                 // resize current Cell
1351                                 pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1352                             }
1353
1354                             InternalType* pIT = pCell->extract(pEH->getArgs());
1355                             workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
1356                             workFields.front()->setReinsertion();
1357                         }
1358                     }
1359                     else
1360                     {
1361                         if ((*iterFields)->isCellExp())
1362                         {
1363                             // a(x){y}
1364                             if (pEH->needResize())
1365                             {
1366                                 if (pEH->getArgsDims() == 1)
1367                                 {
1368                                     std::wostringstream os;
1369                                     os << _W("Invalid index.");
1370                                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1371                                 }
1372
1373                                 // resize current Cell
1374                                 pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1375                             }
1376
1377                             InternalType* pIT = pCell->extract(pEH->getArgs());
1378                             workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
1379                             workFields.front()->setReinsertion();
1380                         }
1381                         else
1382                         {
1383                             // only a(x)
1384                             std::wostringstream os;
1385                             os << _W("Wrong insertion in a Cell.");
1386                             throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1387                         }
1388                     }
1389                 }
1390                 else
1391                 {
1392                     std::wostringstream os;
1393                     os << _W("Wrong insertion in a Cell.");
1394                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1395                 }
1396             }
1397             else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
1398             {
1399                 // call userType extract method
1400                 if (pEH->getArgs())
1401                 {
1402                     // a(x)
1403                     InternalType* pExtract = pITCurrent->getAs<UserType>()->extract(pEH->getArgs());
1404                     if (pExtract == NULL)
1405                     {
1406                         // call overload
1407                         pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1408                     }
1409
1410                     if ((*iterFields)->getExp() == NULL)
1411                     {
1412                         // a(x)(y)
1413                         // extract a(x) and push_BACK to extract next level
1414                         workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1415                         workFields.back()->setReinsertion();
1416                     }
1417                     else
1418                     {
1419                         // a(x).b
1420                         // extract a(x) and push_FRONT to extract b from a(x)
1421                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1422                         workFields.front()->setReinsertion();
1423                     }
1424                 }
1425                 else
1426                 {
1427                     // a.x, get string "x"
1428                     std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1429
1430                     // create arg with next field
1431                     typed_list* args = new typed_list();
1432                     args->push_back(new String(pwcsFieldname.c_str()));
1433                     pEH->setArgs(args);
1434
1435                     // check if the field x is the last field
1436                     std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1437                     ++iterFieldsNext;
1438                     if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1439                     {
1440                         // a.x where x is the last field
1441                         // insert directly in x instead of extract then insert
1442                         ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1443                         pEHNext->setReinsertion();
1444                         evalFields.push_back(pEHNext);
1445                         if (workFields.empty())
1446                         {
1447                             break;
1448                         }
1449                     }
1450                     else
1451                     {
1452                         InternalType* pExtract = pITCurrent->getAs<UserType>()->extract(args);
1453                         if (pExtract == NULL)
1454                         {
1455                             // call overload
1456                             pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1457                         }
1458
1459                         // append extraction of a.x for next level.
1460                         workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1461                         workFields.back()->setReinsertion();
1462                     }
1463                 }
1464             }
1465             else if (pITCurrent->isCallable())
1466             {
1467                 std::wostringstream os;
1468                 os << _W("Wrong insertion : function or macro are not expected.");
1469                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1470             }
1471             else
1472             {
1473                 InternalType* pIT = new Struct(1, 1);
1474                 pEH->setCurrent(pIT);
1475                 pEH->setReinsertion();
1476
1477                 workFields.push_front(pEH);
1478                 evalFields.pop_back();
1479             }
1480
1481             if (workFields.front()->getLevel() == (*iterFields)->getLevel())
1482             {
1483                 // go to next field
1484                 iterFields++;
1485             }
1486         }
1487
1488         //*** insert what we have to assign             ***//
1489         //*** in case where the last field is a CallExp ***//
1490         while (workFields.empty() == false)
1491         {
1492             ExpHistory* pEH = workFields.front();
1493             evalFields.push_back(pEH);
1494             workFields.pop_front();
1495
1496             typed_list* pArgs = pEH->getArgs();
1497
1498             // should never occured
1499             if (pArgs == NULL)
1500             {
1501                 std::wostringstream os;
1502                 os << _W("evaluateFields : Cannot insert without arguments.");
1503                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1504             }
1505
1506             if (pEH->isCellExp())
1507             {
1508                 Cell* pCell = pEH->getCurrent()->getAs<Cell>();
1509                 // insert "something" in b{x}
1510                 if ((*pArgs)[0]->isString())
1511                 {
1512                     std::wostringstream os;
1513                     os << _W("Wrong insertion in a Cell.");
1514                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1515                 }
1516
1517                 pCell->insertCell(pArgs, _pAssignValue);
1518             }
1519             else
1520             {
1521                 // insert "something" in b(x,y)
1522                 InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
1523                 if (pIT == NULL)
1524                 {
1525                     std::wostringstream os;
1526                     os << _W("Submatrix incorrectly defined.\n");
1527                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1528                 }
1529
1530                 if (pEH->setCurrent(pIT))
1531                 {
1532                     pEH->setReinsertion();
1533                 }
1534             }
1535         }
1536
1537         //*** update fields ***//
1538         while (evalFields.empty() == false)
1539         {
1540             ExpHistory* pEH = evalFields.back();
1541             if (pEH->reinsertMe())
1542             {
1543                 ExpHistory* pEHParent = pEH->getParent();
1544
1545                 if (pEHParent == NULL)
1546                 {
1547                     ctx->put(pEH->getExp()->getStack(), pEH->getCurrent());
1548                     break;
1549                 }
1550
1551                 typed_list* pParentArgs = pEHParent->getArgs();
1552                 if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
1553                 {
1554                     InternalType* pParent = pEHParent->getCurrent();
1555                     if (pParent->isStruct())
1556                     {
1557                         Struct* pStruct = pParent->getAs<Struct>();
1558                         pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
1559                         evalFields.pop_back();
1560                         delete pEH;
1561                         continue;
1562                     }
1563                     else if (pParent->isTList() || pParent->isMList())
1564                     {
1565                         TList* pTL = pParent->getAs<TList>();
1566                         if (pParentArgs)
1567                         {
1568                             // In case where pTL is in several scilab variable,
1569                             // we have to clone it for keep the other variables unchanged.
1570                             if (pTL->getRef() > 1)
1571                             {
1572                                 pTL = pTL->clone()->getAs<TList>();
1573                             }
1574
1575                             pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
1576
1577                             if (pEH->getParent()->setCurrent(pTL))
1578                             {
1579                                 pEH->getParent()->setReinsertion();
1580                                 pEH->resetReinsertion();
1581                             }
1582
1583                             evalFields.pop_back();
1584                             delete pEH;
1585                             continue;
1586                         }
1587                         else
1588                         {
1589                             if (pTL->exists(pEH->getExpAsString()))
1590                             {
1591                                 // In case where pTL is in several scilab variable,
1592                                 // we have to clone it for keep the other variables unchanged.
1593                                 if (pTL->getRef() > 1)
1594                                 {
1595                                     pTL = pTL->clone()->getAs<TList>();
1596                                 }
1597
1598                                 pTL->set(pEH->getExpAsString(), pEH->getCurrent());
1599
1600                                 if (pEH->getParent()->setCurrent(pTL))
1601                                 {
1602                                     pEH->getParent()->setReinsertion();
1603                                     pEH->resetReinsertion();
1604                                 }
1605
1606                                 evalFields.pop_back();
1607                                 delete pEH;
1608                                 continue;
1609                             }
1610
1611                             pParentArgs = new typed_list();
1612                             pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
1613                         }
1614                     }
1615                     else if (pParent->isCell())
1616                     {
1617                         Cell* pCell = pParent->getAs<Cell>();
1618                         if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
1619                         {
1620                             // a{x}.b => reinsert b in a{x}
1621                             pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
1622                             pEHParent->setReinsertion();
1623                             evalFields.pop_back();
1624                             delete pEH;
1625                             continue;
1626                         }
1627                     }
1628                 }
1629
1630                 InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
1631                 if (pIT == NULL)
1632                 {
1633                     std::wostringstream os;
1634                     os << _W("Submatrix incorrectly defined.\n");
1635                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1636                 }
1637
1638                 if (pEHParent->setCurrent(pIT))
1639                 {
1640                     pEHParent->setReinsertion();
1641                 }
1642
1643                 if (pEHParent->getArgs() == NULL)
1644                 {
1645                     delete pParentArgs;
1646                 }
1647             }
1648
1649             if (pEH->getCurrent())
1650             {
1651                 pEH->getCurrent()->killMe();
1652             }
1653
1654             evalFields.pop_back();
1655             delete pEH;
1656         }
1657
1658         if (!evalFields.empty())
1659         {
1660             for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
1661             {
1662                 delete *i;
1663             }
1664         }
1665
1666         return ctx->getCurrentLevel(pFirstField->getExp()->getSymbol());
1667     }
1668     catch (ast::ScilabError error)
1669     {
1670         for (std::list<ExpHistory*>::reverse_iterator i = workFields.rbegin(); i != workFields.rend(); ++i)
1671         {
1672             (*i)->setDeleteCurrent(true);
1673             delete *i;
1674         }
1675
1676         for (std::list<ExpHistory*>::reverse_iterator i = evalFields.rbegin(); i != evalFields.rend(); ++i)
1677         {
1678             (*i)->setDeleteCurrent(true);
1679             delete *i;
1680         }
1681
1682         _pAssignValue->killMe();
1683         throw error;
1684     }
1685 }
1686
1687 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
1688 {
1689     InternalType* pOut = NULL;
1690     InternalType *pIL = NULL;
1691     //fisrt extract implicit list
1692     if (_pInsert->isColon())
1693     {
1694         //double* pdbl = NULL;
1695         //_pInsert = new Double(-1, -1, &pdbl);
1696         //pdbl[0] = 1;
1697         pIL = Double::Identity(-1, -1);
1698         _pInsert->killMe();
1699         _pInsert = pIL;
1700     }
1701     else if (_pInsert->isImplicitList())
1702     {
1703         pIL = _pInsert->getAs<ImplicitList>()->extractFullMatrix();
1704         if (pIL && pIL->isDeletable())
1705         {
1706             _pInsert->killMe();
1707             _pInsert = pIL;
1708         }
1709     }
1710     else if (_pInsert->isContainer() && _pInsert->isRef())
1711     {
1712         //std::cout << "assign container type during insertion" << std::endl;
1713         //InternalType* pIL = _pInsert->clone();
1714         //_pInsert = pIL;
1715     }
1716
1717     if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar == NULL)
1718     {
1719         // l(x) = [] when l is not defined => create l = []
1720         pOut = Double::Empty();
1721     }
1722     else if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1723     {
1724         //insert [] so deletion except for Struct and List which can insert []
1725         InternalType::ScilabType varType = _pVar->getType();
1726         switch (varType)
1727         {
1728             case InternalType::ScilabDouble :
1729             {
1730                 pOut = _pVar->getAs<Double>()->remove(_pArgs);
1731                 break;
1732             }
1733             case InternalType::ScilabString :
1734             {
1735                 pOut = _pVar->getAs<String>()->remove(_pArgs);
1736                 break;
1737             }
1738             case InternalType::ScilabCell :
1739             {
1740                 pOut = _pVar->getAs<Cell>()->remove(_pArgs);
1741                 break;
1742             }
1743             case InternalType::ScilabBool :
1744             {
1745                 pOut = _pVar->getAs<Bool>()->remove(_pArgs);
1746                 break;
1747             }
1748             case InternalType::ScilabPolynom :
1749             {
1750                 pOut = _pVar->getAs<Polynom>()->remove(_pArgs);
1751                 break;
1752             }
1753             case InternalType::ScilabInt8 :
1754             {
1755                 pOut = _pVar->getAs<Int8>()->remove(_pArgs);
1756                 break;
1757             }
1758             case InternalType::ScilabUInt8 :
1759             {
1760                 pOut = _pVar->getAs<UInt8>()->remove(_pArgs);
1761                 break;
1762             }
1763             case InternalType::ScilabInt16 :
1764             {
1765                 pOut = _pVar->getAs<Int16>()->remove(_pArgs);
1766                 break;
1767             }
1768             case InternalType::ScilabUInt16 :
1769             {
1770                 pOut = _pVar->getAs<UInt16>()->remove(_pArgs);
1771                 break;
1772             }
1773             case InternalType::ScilabInt32 :
1774             {
1775                 pOut = _pVar->getAs<Int32>()->remove(_pArgs);
1776                 break;
1777             }
1778             case InternalType::ScilabUInt32 :
1779             {
1780                 pOut = _pVar->getAs<UInt32>()->remove(_pArgs);
1781                 break;
1782             }
1783             case InternalType::ScilabInt64 :
1784             {
1785                 pOut = _pVar->getAs<Int64>()->remove(_pArgs);
1786                 break;
1787             }
1788             case InternalType::ScilabUInt64 :
1789             {
1790                 pOut = _pVar->getAs<UInt64>()->remove(_pArgs);
1791                 break;
1792             }
1793             case InternalType::ScilabSparse :
1794             {
1795                 pOut = _pVar->getAs<Sparse>()->remove(_pArgs);
1796                 break;
1797             }
1798             case InternalType::ScilabSparseBool :
1799             {
1800                 pOut = _pVar->getAs<SparseBool>()->remove(_pArgs);
1801                 break;
1802             }
1803             case InternalType::ScilabStruct :
1804             {
1805                 pOut = _pVar->getAs<Struct>()->insert(_pArgs, _pInsert);
1806                 break;
1807             }
1808             case InternalType::ScilabHandle :
1809             {
1810                 GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
1811                 if ((*_pArgs)[0]->isString())
1812                 {
1813                     String *pS = (*_pArgs)[0]->getAs<String>();
1814
1815                     typed_list in;
1816                     typed_list out;
1817                     optional_list opt;
1818                     ast::ExecVisitor exec;
1819
1820                     in.push_back(pH);
1821                     in.push_back(pS);
1822                     in.push_back(_pInsert);
1823
1824                     Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1825                     Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
1826                     if (ret == Callable::OK)
1827                     {
1828                         pOut = _pVar;
1829                     }
1830                 }
1831                 else
1832                 {
1833                     pOut = pH->insert(_pArgs, _pInsert);
1834                 }
1835
1836                 break;
1837             }
1838             default :
1839             {
1840                 //overload !
1841                 pOut = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1842                 break;
1843             }
1844         }
1845     }
1846     else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<Double>()->getSize() == 0))
1847     {
1848         //insert in a new variable or []
1849         //call static insert function
1850         //if _pVar == NULL and pArg is single string, it's a struct creation
1851         if ((*_pArgs)[0]->isString())
1852         {
1853             String *pS = (*_pArgs)[0]->getAs<String>();
1854             Struct* pStr = new Struct(1, 1);
1855
1856             if (_pArgs->size() != 1 || pS->isScalar() == false)
1857             {
1858                 if (pIL)
1859                 {
1860                     pIL->killMe();
1861                 }
1862                 //manage error
1863                 std::wostringstream os;
1864                 os << _W("Invalid Index.\n");
1865                 throw ast::ScilabError(os.str(), 999, e.getLocation());
1866             }
1867
1868             pStr->addField(pS->get(0));
1869             pStr->get(0)->set(pS->get(0), _pInsert);
1870             pOut = pStr;
1871         }
1872         else
1873         {
1874             switch (_pInsert->getType())
1875             {
1876                 case InternalType::ScilabDouble :
1877                     pOut = Double::insertNew(_pArgs, _pInsert);
1878                     break;
1879                 case InternalType::ScilabString :
1880                     pOut = String::insertNew(_pArgs, _pInsert);
1881                     break;
1882                 case InternalType::ScilabCell :
1883                     pOut = Cell::insertNew(_pArgs, _pInsert);
1884                     break;
1885                 case InternalType::ScilabBool :
1886                     pOut = Bool::insertNew(_pArgs, _pInsert);
1887                     break;
1888                 case InternalType::ScilabPolynom :
1889                     pOut = Polynom::insertNew(_pArgs, _pInsert);
1890                     break;
1891                 case InternalType::ScilabInt8 :
1892                     pOut = Int8::insertNew(_pArgs, _pInsert);
1893                     break;
1894                 case InternalType::ScilabUInt8 :
1895                     pOut = UInt8::insertNew(_pArgs, _pInsert);
1896                     break;
1897                 case InternalType::ScilabInt16 :
1898                     pOut = Int16::insertNew(_pArgs, _pInsert);
1899                     break;
1900                 case InternalType::ScilabUInt16 :
1901                     pOut = UInt16::insertNew(_pArgs, _pInsert);
1902                     break;
1903                 case InternalType::ScilabInt32 :
1904                     pOut = Int32::insertNew(_pArgs, _pInsert);
1905                     break;
1906                 case InternalType::ScilabUInt32 :
1907                     pOut = UInt32::insertNew(_pArgs, _pInsert);
1908                     break;
1909                 case InternalType::ScilabInt64 :
1910                     pOut = Int64::insertNew(_pArgs, _pInsert);
1911                     break;
1912                 case InternalType::ScilabUInt64 :
1913                     pOut = UInt64::insertNew(_pArgs, _pInsert);
1914                     break;
1915                 case InternalType::ScilabSparse :
1916                     pOut = Sparse::insertNew(_pArgs, _pInsert);
1917                     break;
1918                 case InternalType::ScilabSparseBool :
1919                     pOut = SparseBool::insertNew(_pArgs, _pInsert);
1920                     break;
1921                 case InternalType::ScilabHandle:
1922                     pOut = GraphicHandle::insertNew(_pArgs, _pInsert);
1923                     break;
1924                 default :
1925                 {
1926                     // overload
1927                     Double* pEmpty = Double::Empty();
1928                     pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1929                     pEmpty->killMe();
1930                     break;
1931                 }
1932             }
1933         }
1934     }
1935     else
1936     {
1937         //call type insert function
1938         InternalType* pRet = NULL;
1939
1940         //check types compatibilties
1941         if (_pVar->isDouble() && _pInsert->isDouble())
1942         {
1943             pRet = _pVar->getAs<Double>()->insert(_pArgs, _pInsert);
1944         }
1945         else if (_pVar->isDouble() && _pInsert->isSparse())
1946         {
1947             Sparse* pSp = _pInsert->getAs<Sparse>();
1948             Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1949             pSp->fill(*pD);
1950             pRet = _pVar->getAs<Double>()->insert(_pArgs, pD);
1951             delete pD;
1952         }
1953         else if (_pVar->isString() && _pInsert->isString())
1954         {
1955             pRet = _pVar->getAs<String>()->insert(_pArgs, _pInsert);
1956         }
1957         else if (_pVar->isCell() && _pInsert->isCell())
1958         {
1959             pRet = _pVar->getAs<Cell>()->insert(_pArgs, _pInsert);
1960         }
1961         else if (_pVar->isBool() && _pInsert->isBool())
1962         {
1963             pRet = _pVar->getAs<Bool>()->insert(_pArgs, _pInsert);
1964         }
1965         else if (_pVar->isSparse() && _pInsert->isSparse())
1966         {
1967             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert->getAs<Sparse>());
1968         }
1969         else if (_pVar->isSparse() && _pInsert->isDouble())
1970         {
1971             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert);
1972         }
1973         else if (_pVar->isSparseBool() && _pInsert->isSparseBool())
1974         {
1975             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert->getAs<SparseBool>());
1976         }
1977         else if (_pVar->isSparseBool() && _pInsert->isBool())
1978         {
1979             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert);
1980         }
1981         else if (_pVar->isDouble() && _pInsert->isPoly())
1982         {
1983             Double* pDest = _pVar->getAs<Double>();
1984             Polynom* pIns = _pInsert->getAs<Polynom>();
1985             int iSize = pDest->getSize();
1986             int* piRanks = new int[iSize];
1987             memset(piRanks, 0x00, iSize * sizeof(int));
1988             Polynom* pP = new Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1989             delete[] piRanks;
1990             pP->setComplex(pDest->isComplex());
1991
1992             if (pP->isComplex())
1993             {
1994                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1995                 {
1996                     double dblR = pDest->get(idx);
1997                     double dblI = pDest->getImg(idx);
1998                     pP->get(idx)->setCoef(&dblR, &dblI);
1999                 }
2000             }
2001             else
2002             {
2003                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2004                 {
2005                     double dblR = pDest->get(idx);
2006                     pP->get(idx)->setCoef(&dblR, NULL);
2007                 }
2008             }
2009
2010             pRet = pP->insert(_pArgs, pIns);
2011         }
2012         else if (_pVar->isPoly() && _pInsert->isDouble())
2013         {
2014             Polynom* pDest = _pVar->getAs<Polynom>();
2015             Double* pIns = _pInsert->getAs<Double>();
2016             bool isComplexIns = pIns->isComplex();
2017             int iSize = pIns->getSize();
2018             int* piRanks = new int[iSize];
2019             memset(piRanks, 0x00, iSize * sizeof(int));
2020
2021             //create a new polynom with Double to insert it into dest polynom
2022             Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
2023             delete[] piRanks;
2024
2025             if (isComplexIns)
2026             {
2027                 double* pR = pIns->get();
2028                 double* pI = pIns->getImg();
2029                 SinglePoly** pSP = pP->get();
2030                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2031                 {
2032                     double dblR = pR[idx];
2033                     double dblI = pI[idx];
2034                     pSP[idx]->setComplex(true);
2035                     pSP[idx]->setCoef(&dblR, &dblI);
2036                 }
2037             }
2038             else
2039             {
2040                 double* pdblR = pIns->get();
2041                 SinglePoly** pSP = pP->get();
2042                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2043                 {
2044                     double dblR = pdblR[idx];
2045                     pSP[idx]->setCoef(&dblR, NULL);
2046                 }
2047             }
2048
2049             pRet = pDest->insert(_pArgs, pP);
2050             pP->killMe();
2051         }
2052         else if (_pVar->isPoly() && _pInsert->isPoly())
2053         {
2054             pRet = _pVar->getAs<Polynom>()->insert(_pArgs, _pInsert);
2055         }
2056         else if (_pVar->isInt8() && _pInsert->isInt8())
2057         {
2058             pRet = _pVar->getAs<Int8>()->insert(_pArgs, _pInsert);
2059         }
2060         else if (_pVar->isUInt8() && _pInsert->isUInt8())
2061         {
2062             pRet = _pVar->getAs<UInt8>()->insert(_pArgs, _pInsert);
2063         }
2064         else if (_pVar->isInt16() && _pInsert->isInt16())
2065         {
2066             pRet = _pVar->getAs<Int16>()->insert(_pArgs, _pInsert);
2067         }
2068         else if (_pVar->isUInt16() && _pInsert->isUInt16())
2069         {
2070             pRet = _pVar->getAs<UInt16>()->insert(_pArgs, _pInsert);
2071         }
2072         else if (_pVar->isInt32() && _pInsert->isInt32())
2073         {
2074             pRet = _pVar->getAs<Int32>()->insert(_pArgs, _pInsert);
2075         }
2076         else if (_pVar->isUInt32() && _pInsert->isUInt32())
2077         {
2078             pRet = _pVar->getAs<UInt32>()->insert(_pArgs, _pInsert);
2079         }
2080         else if (_pVar->isInt64() && _pInsert->isInt64())
2081         {
2082             pRet = _pVar->getAs<Int64>()->insert(_pArgs, _pInsert);
2083         }
2084         else if (_pVar->isUInt64() && _pInsert->isUInt64())
2085         {
2086             pRet = _pVar->getAs<UInt64>()->insert(_pArgs, _pInsert);
2087         }
2088         else if (_pVar->isStruct())
2089         {
2090             Struct* pStruct = _pVar->getAs<Struct>();
2091             // insert something in a field of a struct
2092             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2093             {
2094                 //s("x") = y
2095                 String *pS = (*_pArgs)[0]->getAs<String>();
2096                 if (pS->isScalar() == false)
2097                 {
2098                     if (pIL)
2099                     {
2100                         pIL->killMe();
2101                     }
2102                     //manage error
2103                     std::wostringstream os;
2104                     os << _W("Invalid Index.\n");
2105                     throw ast::ScilabError(os.str(), 999, e.getLocation());
2106                 }
2107
2108                 if (_pInsert->isListDelete())
2109                 {
2110                     /* Remove a field */
2111                     pStruct->removeField(pS->get(0));
2112                 }
2113                 else
2114                 {
2115                     /* Add a field */
2116                     pStruct->addField(pS->get(0));
2117                     for (int i = 0; i < pStruct->getSize(); i++)
2118                     {
2119                         pStruct->get(i)->set(pS->get(0), _pInsert);
2120                     }
2121                 }
2122                 pRet = pStruct;
2123             }
2124             else // insert something in a struct
2125             {
2126                 if (_pInsert->isStruct())
2127                 {
2128                     String* pStrFieldsName = pStruct->getFieldNames();
2129                     Struct* pStructInsert = _pInsert->clone()->getAs<Struct>();
2130                     String* pStrInsertFieldsName = pStructInsert->getFieldNames();
2131                     Struct* pStructRet = NULL;
2132
2133                     // if not an empty struct
2134                     if (pStrFieldsName)
2135                     {
2136                         // insert fields of pStruct in pStructInsert
2137                         for (int i = pStrFieldsName->getSize(); i > 0; i--)
2138                         {
2139                             if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
2140                             {
2141                                 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
2142                             }
2143                             else
2144                             {
2145                                 std::wstring pwcsField = pStrFieldsName->get(i - 1);
2146                                 List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
2147
2148                                 for (int i = 0; i < pLExtract->getSize(); i++)
2149                                 {
2150                                     // protect element wich are not cloned before call removeField.
2151                                     pLExtract->get(i)->IncreaseRef();
2152                                 }
2153
2154                                 pStructInsert->removeField(pwcsField);
2155                                 pStructInsert->addFieldFront(pwcsField);
2156
2157                                 for (int i = 0; i < pLExtract->getSize(); i++)
2158                                 {
2159                                     // set elements in the new position
2160                                     pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
2161                                     pLExtract->get(i)->DecreaseRef();
2162                                 }
2163
2164                                 pLExtract->killMe();
2165                             }
2166                         }
2167
2168                         pStrFieldsName->killMe();
2169                     }
2170
2171                     // insert elements in following pArgs
2172                     pRet = pStruct->insert(_pArgs, pStructInsert);
2173                     pStructRet = pRet->getAs<Struct>();
2174
2175                     pStructInsert->killMe();
2176
2177                     // insert fields of pStructInsert in pRet
2178                     for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
2179                     {
2180                         if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
2181                         {
2182                             pStructRet->addField(pStrInsertFieldsName->get(i));
2183                         }
2184                     }
2185
2186                     pStrInsertFieldsName->killMe();
2187                 }
2188                 else
2189                 {
2190                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2191                 }
2192             }
2193         }
2194         else if (_pVar->isTList() || _pVar->isMList())
2195         {
2196             TList* pTL = _pVar->getAs<TList>();
2197             if (_pArgs->size() == 1)
2198             {
2199                 if ((*_pArgs)[0]->isString())
2200                 {
2201                     //s("x") = y
2202                     String *pS = (*_pArgs)[0]->getAs<String>();
2203                     if (pS->isScalar() == false)
2204                     {
2205                         if (pIL)
2206                         {
2207                             pIL->killMe();
2208                         }
2209
2210                         //manage error
2211                         std::wostringstream os;
2212                         os << _W("Invalid Index.\n");
2213                         throw ast::ScilabError(os.str(), 999, e.getLocation());
2214                     }
2215
2216                     if (_pInsert->isListDelete())
2217                     {
2218                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2219                     }
2220
2221                     if (pTL->exists(pS->get(0)))
2222                     {
2223                         pTL->set(pS->get(0), _pInsert);
2224                         pRet = pTL;
2225                     }
2226                     else
2227                     {
2228                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2229
2230                         //ExecVisitor exec;
2231                         //typed_list in;
2232                         //typed_list out;
2233                         //std::wstring function_name = L"%l_e";
2234
2235                         //_pInsert->IncreaseRef();
2236                         //in.push_back(_pInsert);
2237
2238                         //Overload::call(function_name, in, 1, out, &exec);
2239                         //_pInsert->DecreaseRef();
2240
2241                         //if (out.size() != 0)
2242                         //{
2243                         //    pRet = in[0];
2244                         //}
2245                     }
2246                 }
2247                 else
2248                 {
2249                     // s(x)
2250                     if (_pVar->isMList())
2251                     {
2252                         pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2253                     }
2254                     else
2255                     {
2256                         // In case where pTL is in several scilab variable,
2257                         // we have to clone it for keep the other variables unchanged.
2258                         if (pTL->getRef() > 1)
2259                         {
2260                             pTL = pTL->clone()->getAs<TList>();
2261                         }
2262
2263                         pRet = pTL->insert(_pArgs, _pInsert);
2264
2265                         // If we have inserted something else than a String
2266                         // in the first element, the TList have to be a List.
2267                         if (pTL->get(0)->isString() == false)
2268                         {
2269                             List* pL = new List();
2270                             for (int i = 0; i < pTL->getSize(); i++)
2271                             {
2272                                 pL->append(pTL->get(i));
2273                             }
2274
2275                             pTL->killMe();
2276                             pRet = pL;
2277                         }
2278                     }
2279                 }
2280             }
2281             else
2282             {
2283                 if (_pVar->isMList())
2284                 {
2285                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2286                 }
2287                 else
2288                 {
2289                     // call the overload if it exists.
2290                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2291                     if (pRet == NULL)
2292                     {
2293                         // else normal insert
2294                         pRet = pTL->insert(_pArgs, _pInsert);
2295                     }
2296                 }
2297             }
2298         }
2299         else if (_pVar->isList())
2300         {
2301             List* pL = NULL;
2302             // In case where pL is in several scilab variable,
2303             // we have to clone it for keep the other variables unchanged.
2304             if (_pVar->getRef() > 1)
2305             {
2306                 pL = _pVar->clone()->getAs<List>();
2307                 pRet = pL->insert(_pArgs, _pInsert);
2308                 if (pRet == NULL)
2309                 {
2310                     pL->killMe();
2311                     // call overload
2312                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2313                 }
2314             }
2315             else
2316             {
2317                 pL = _pVar->getAs<List>();
2318                 pRet = pL->insert(_pArgs, _pInsert);
2319                 if (pRet == NULL)
2320                 {
2321                     // call overload
2322                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2323                 }
2324             }
2325         }
2326         else if (_pVar->isHandle())
2327         {
2328             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2329             {
2330                 //s(["x"])
2331                 GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
2332                 String *pS = (*_pArgs)[0]->getAs<String>();
2333                 typed_list in;
2334                 typed_list out;
2335                 optional_list opt;
2336                 ast::ExecVisitor exec;
2337
2338                 in.push_back(pH);
2339                 in.push_back(pS);
2340                 in.push_back(_pInsert);
2341
2342                 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2343                 if (pCall)
2344                 {
2345                     Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
2346                     if (ret == Callable::OK)
2347                     {
2348                         pRet = _pVar;
2349                     }
2350                 }
2351             }
2352             else
2353             {
2354                 pRet = _pVar->getAs<GraphicHandle>()->insert(_pArgs, _pInsert);
2355             }
2356         }
2357         else if (_pVar->isUserType())
2358         {
2359             for (int i = 0; i < _pArgs->size(); i++)
2360             {
2361                 if ((*_pArgs)[i]->isImplicitList())
2362                 {
2363                     types::ImplicitList* pIL = (*_pArgs)[i]->getAs<types::ImplicitList>();
2364                     if (pIL->isComputable())
2365                     {
2366                         InternalType* pIT = pIL->extractFullMatrix();
2367                         (*_pArgs)[i]->killMe();
2368                         (*_pArgs)[i] = pIT;
2369                     }
2370                 }
2371             }
2372
2373             pRet = _pVar->getAs<UserType>()->insert(_pArgs, _pInsert);
2374             if (pRet == NULL)
2375             {
2376                 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2377             }
2378         }
2379         else
2380         {
2381             // overload
2382             pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2383         }
2384
2385         pOut = pRet;
2386     }
2387
2388     if (pIL)
2389     {
2390         pIL->killMe();
2391     }
2392
2393     return pOut;
2394 }
2395
2396 void callOnPrompt(void)
2397 {
2398     static symbol::Variable* onPrompt = NULL;
2399
2400     if (onPrompt == NULL)
2401     {
2402         onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2403     }
2404
2405     InternalType* pOnPrompt = NULL;
2406     pOnPrompt = onPrompt->get();
2407     if (pOnPrompt != NULL && pOnPrompt->isCallable())
2408     {
2409         typed_list in;
2410         typed_list out;
2411         optional_list opt;
2412         ast::ExecVisitor execCall;
2413         pOnPrompt->getAs<Callable>()->call(in, opt, 1, out, &execCall);
2414     }
2415 }
2416
2417 List* getPropertyTree(ast::Exp* e, List* pList)
2418 {
2419
2420     //a.b
2421     ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(e);
2422     if (pVar)
2423     {
2424         pList->append(new String(pVar->getSymbol().getName().c_str()));
2425         return pList;
2426     }
2427
2428     //a(x).b
2429     ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(e);
2430     if (pCall)
2431     {
2432         pList = getPropertyTree(&pCall->getName(), pList);
2433         ast::ExecVisitor exec;
2434         ast::exps_t exps = pCall->getArgs();
2435         for (auto exp : exps)
2436         {
2437             try
2438             {
2439                 exp->accept(exec);
2440                 pList->append(exec.getResult());
2441                 exec.clearResult();
2442             }
2443             catch (ast::ScilabException e)
2444             {
2445                 throw e;
2446             }
2447         }
2448         return pList;
2449     }
2450
2451     //a.b.c
2452     ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(e);
2453     if (pField)
2454     {
2455         pList = getPropertyTree(pField->getHead(), pList);
2456         pList = getPropertyTree(pField->getTail(), pList);
2457         return pList;
2458     }
2459
2460     return pList;
2461 }
2462
2463 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2464 {
2465     ast::Exp* newTree = NULL;
2466     unsigned char *newast = NULL;
2467     ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2468     ast::DeserializeVisitor* d = NULL;
2469
2470     if (_msg.empty())
2471     {
2472         unsigned char* astbin = s->serialize();
2473         //call ocamlpro typer
2474         //char *newast = ocamlpro_typer(astbin);
2475         //free(astbin);
2476
2477         //for debug
2478         newast = astbin;
2479
2480         d = new ast::DeserializeVisitor(newast);
2481         newTree = d->deserialize();
2482     }
2483     else
2484     {
2485         std::wstring msgS(_msg + L" serialize");
2486         std::wstring msgD(_msg + L" deserialize");
2487
2488         Timer timer;
2489         timer.start();
2490         unsigned char* astbin = s->serialize();
2491         timer.check(msgS.c_str());
2492
2493         //call ocamlpro typer
2494         //char *newast = ocamlpro_typer(astbin);
2495         //free(astbin);
2496
2497         //for debug
2498         newast = astbin;
2499
2500         timer.start();
2501         d = new ast::DeserializeVisitor(newast);
2502         newTree = d->deserialize();
2503         timer.check(msgD.c_str());
2504     }
2505
2506     free(newast);
2507     delete s;
2508     delete d;
2509     return newTree;
2510 }