fix ast message when insert in handle
[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         throw error;
1683     }
1684 }
1685
1686 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
1687 {
1688     InternalType* pOut = NULL;
1689     InternalType *pIL = NULL;
1690     //fisrt extract implicit list
1691     if (_pInsert->isColon())
1692     {
1693         //double* pdbl = NULL;
1694         //_pInsert = new Double(-1, -1, &pdbl);
1695         //pdbl[0] = 1;
1696         pIL = Double::Identity(-1, -1);
1697         _pInsert->killMe();
1698         _pInsert = pIL;
1699     }
1700     else if (_pInsert->isImplicitList())
1701     {
1702         pIL = _pInsert->getAs<ImplicitList>()->extractFullMatrix();
1703         if (pIL && pIL->isDeletable())
1704         {
1705             _pInsert->killMe();
1706             _pInsert = pIL;
1707         }
1708     }
1709     else if (_pInsert->isContainer() && _pInsert->isRef())
1710     {
1711         //std::cout << "assign container type during insertion" << std::endl;
1712         //InternalType* pIL = _pInsert->clone();
1713         //_pInsert = pIL;
1714     }
1715
1716     if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar == NULL)
1717     {
1718         // l(x) = [] when l is not defined => create l = []
1719         pOut = Double::Empty();
1720     }
1721     else if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1722     {
1723         //insert [] so deletion except for Struct and List which can insert []
1724         InternalType::ScilabType varType = _pVar->getType();
1725         switch (varType)
1726         {
1727             case InternalType::ScilabDouble :
1728             {
1729                 pOut = _pVar->getAs<Double>()->remove(_pArgs);
1730                 break;
1731             }
1732             case InternalType::ScilabString :
1733             {
1734                 pOut = _pVar->getAs<String>()->remove(_pArgs);
1735                 break;
1736             }
1737             case InternalType::ScilabCell :
1738             {
1739                 pOut = _pVar->getAs<Cell>()->remove(_pArgs);
1740                 break;
1741             }
1742             case InternalType::ScilabBool :
1743             {
1744                 pOut = _pVar->getAs<Bool>()->remove(_pArgs);
1745                 break;
1746             }
1747             case InternalType::ScilabPolynom :
1748             {
1749                 pOut = _pVar->getAs<Polynom>()->remove(_pArgs);
1750                 break;
1751             }
1752             case InternalType::ScilabInt8 :
1753             {
1754                 pOut = _pVar->getAs<Int8>()->remove(_pArgs);
1755                 break;
1756             }
1757             case InternalType::ScilabUInt8 :
1758             {
1759                 pOut = _pVar->getAs<UInt8>()->remove(_pArgs);
1760                 break;
1761             }
1762             case InternalType::ScilabInt16 :
1763             {
1764                 pOut = _pVar->getAs<Int16>()->remove(_pArgs);
1765                 break;
1766             }
1767             case InternalType::ScilabUInt16 :
1768             {
1769                 pOut = _pVar->getAs<UInt16>()->remove(_pArgs);
1770                 break;
1771             }
1772             case InternalType::ScilabInt32 :
1773             {
1774                 pOut = _pVar->getAs<Int32>()->remove(_pArgs);
1775                 break;
1776             }
1777             case InternalType::ScilabUInt32 :
1778             {
1779                 pOut = _pVar->getAs<UInt32>()->remove(_pArgs);
1780                 break;
1781             }
1782             case InternalType::ScilabInt64 :
1783             {
1784                 pOut = _pVar->getAs<Int64>()->remove(_pArgs);
1785                 break;
1786             }
1787             case InternalType::ScilabUInt64 :
1788             {
1789                 pOut = _pVar->getAs<UInt64>()->remove(_pArgs);
1790                 break;
1791             }
1792             case InternalType::ScilabSparse :
1793             {
1794                 pOut = _pVar->getAs<Sparse>()->remove(_pArgs);
1795                 break;
1796             }
1797             case InternalType::ScilabSparseBool :
1798             {
1799                 pOut = _pVar->getAs<SparseBool>()->remove(_pArgs);
1800                 break;
1801             }
1802             case InternalType::ScilabStruct :
1803             {
1804                 pOut = _pVar->getAs<Struct>()->insert(_pArgs, _pInsert);
1805                 break;
1806             }
1807             case InternalType::ScilabHandle :
1808             {
1809                 GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
1810                 if ((*_pArgs)[0]->isString())
1811                 {
1812                     String *pS = (*_pArgs)[0]->getAs<String>();
1813
1814                     typed_list in;
1815                     typed_list out;
1816                     optional_list opt;
1817                     ast::ExecVisitor exec;
1818
1819                     in.push_back(pH);
1820                     in.push_back(pS);
1821                     in.push_back(_pInsert);
1822
1823                     Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1824                     Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
1825                     if (ret == Callable::OK)
1826                     {
1827                         pOut = _pVar;
1828                     }
1829                 }
1830                 else
1831                 {
1832                     pOut = pH->insert(_pArgs, _pInsert);
1833                 }
1834
1835                 break;
1836             }
1837             default :
1838             {
1839                 //overload !
1840                 pOut = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1841                 break;
1842             }
1843         }
1844     }
1845     else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<Double>()->getSize() == 0))
1846     {
1847         //insert in a new variable or []
1848         //call static insert function
1849         //if _pVar == NULL and pArg is single string, it's a struct creation
1850         if ((*_pArgs)[0]->isString())
1851         {
1852             String *pS = (*_pArgs)[0]->getAs<String>();
1853             Struct* pStr = new Struct(1, 1);
1854
1855             if (_pArgs->size() != 1 || pS->isScalar() == false)
1856             {
1857                 if (pIL)
1858                 {
1859                     pIL->killMe();
1860                 }
1861                 //manage error
1862                 std::wostringstream os;
1863                 os << _W("Invalid Index.\n");
1864                 throw ast::ScilabError(os.str(), 999, e.getLocation());
1865             }
1866
1867             pStr->addField(pS->get(0));
1868             pStr->get(0)->set(pS->get(0), _pInsert);
1869             pOut = pStr;
1870         }
1871         else
1872         {
1873             switch (_pInsert->getType())
1874             {
1875                 case InternalType::ScilabDouble :
1876                     pOut = Double::insertNew(_pArgs, _pInsert);
1877                     break;
1878                 case InternalType::ScilabString :
1879                     pOut = String::insertNew(_pArgs, _pInsert);
1880                     break;
1881                 case InternalType::ScilabCell :
1882                     pOut = Cell::insertNew(_pArgs, _pInsert);
1883                     break;
1884                 case InternalType::ScilabBool :
1885                     pOut = Bool::insertNew(_pArgs, _pInsert);
1886                     break;
1887                 case InternalType::ScilabPolynom :
1888                     pOut = Polynom::insertNew(_pArgs, _pInsert);
1889                     break;
1890                 case InternalType::ScilabInt8 :
1891                     pOut = Int8::insertNew(_pArgs, _pInsert);
1892                     break;
1893                 case InternalType::ScilabUInt8 :
1894                     pOut = UInt8::insertNew(_pArgs, _pInsert);
1895                     break;
1896                 case InternalType::ScilabInt16 :
1897                     pOut = Int16::insertNew(_pArgs, _pInsert);
1898                     break;
1899                 case InternalType::ScilabUInt16 :
1900                     pOut = UInt16::insertNew(_pArgs, _pInsert);
1901                     break;
1902                 case InternalType::ScilabInt32 :
1903                     pOut = Int32::insertNew(_pArgs, _pInsert);
1904                     break;
1905                 case InternalType::ScilabUInt32 :
1906                     pOut = UInt32::insertNew(_pArgs, _pInsert);
1907                     break;
1908                 case InternalType::ScilabInt64 :
1909                     pOut = Int64::insertNew(_pArgs, _pInsert);
1910                     break;
1911                 case InternalType::ScilabUInt64 :
1912                     pOut = UInt64::insertNew(_pArgs, _pInsert);
1913                     break;
1914                 case InternalType::ScilabSparse :
1915                     pOut = Sparse::insertNew(_pArgs, _pInsert);
1916                     break;
1917                 case InternalType::ScilabSparseBool :
1918                     pOut = SparseBool::insertNew(_pArgs, _pInsert);
1919                     break;
1920                 case InternalType::ScilabHandle:
1921                     pOut = GraphicHandle::insertNew(_pArgs, _pInsert);
1922                     break;
1923                 default :
1924                 {
1925                     // overload
1926                     Double* pEmpty = Double::Empty();
1927                     pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1928                     pEmpty->killMe();
1929                     break;
1930                 }
1931             }
1932         }
1933     }
1934     else
1935     {
1936         //call type insert function
1937         InternalType* pRet = NULL;
1938
1939         //check types compatibilties
1940         if (_pVar->isDouble() && _pInsert->isDouble())
1941         {
1942             pRet = _pVar->getAs<Double>()->insert(_pArgs, _pInsert);
1943         }
1944         else if (_pVar->isDouble() && _pInsert->isSparse())
1945         {
1946             Sparse* pSp = _pInsert->getAs<Sparse>();
1947             Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1948             pSp->fill(*pD);
1949             pRet = _pVar->getAs<Double>()->insert(_pArgs, pD);
1950             delete pD;
1951         }
1952         else if (_pVar->isString() && _pInsert->isString())
1953         {
1954             pRet = _pVar->getAs<String>()->insert(_pArgs, _pInsert);
1955         }
1956         else if (_pVar->isCell() && _pInsert->isCell())
1957         {
1958             pRet = _pVar->getAs<Cell>()->insert(_pArgs, _pInsert);
1959         }
1960         else if (_pVar->isBool() && _pInsert->isBool())
1961         {
1962             pRet = _pVar->getAs<Bool>()->insert(_pArgs, _pInsert);
1963         }
1964         else if (_pVar->isSparse() && _pInsert->isSparse())
1965         {
1966             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert->getAs<Sparse>());
1967         }
1968         else if (_pVar->isSparse() && _pInsert->isDouble())
1969         {
1970             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert);
1971         }
1972         else if (_pVar->isSparseBool() && _pInsert->isSparseBool())
1973         {
1974             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert->getAs<SparseBool>());
1975         }
1976         else if (_pVar->isSparseBool() && _pInsert->isBool())
1977         {
1978             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert);
1979         }
1980         else if (_pVar->isDouble() && _pInsert->isPoly())
1981         {
1982             Double* pDest = _pVar->getAs<Double>();
1983             Polynom* pIns = _pInsert->getAs<Polynom>();
1984             int iSize = pDest->getSize();
1985             int* piRanks = new int[iSize];
1986             memset(piRanks, 0x00, iSize * sizeof(int));
1987             Polynom* pP = new Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1988             delete[] piRanks;
1989             pP->setComplex(pDest->isComplex());
1990
1991             if (pP->isComplex())
1992             {
1993                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1994                 {
1995                     double dblR = pDest->get(idx);
1996                     double dblI = pDest->getImg(idx);
1997                     pP->get(idx)->setCoef(&dblR, &dblI);
1998                 }
1999             }
2000             else
2001             {
2002                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2003                 {
2004                     double dblR = pDest->get(idx);
2005                     pP->get(idx)->setCoef(&dblR, NULL);
2006                 }
2007             }
2008
2009             pRet = pP->insert(_pArgs, pIns);
2010         }
2011         else if (_pVar->isPoly() && _pInsert->isDouble())
2012         {
2013             Polynom* pDest = _pVar->getAs<Polynom>();
2014             Double* pIns = _pInsert->getAs<Double>();
2015             bool isComplexIns = pIns->isComplex();
2016             int iSize = pIns->getSize();
2017             int* piRanks = new int[iSize];
2018             memset(piRanks, 0x00, iSize * sizeof(int));
2019
2020             //create a new polynom with Double to insert it into dest polynom
2021             Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
2022             delete[] piRanks;
2023
2024             if (isComplexIns)
2025             {
2026                 double* pR = pIns->get();
2027                 double* pI = pIns->getImg();
2028                 SinglePoly** pSP = pP->get();
2029                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2030                 {
2031                     double dblR = pR[idx];
2032                     double dblI = pI[idx];
2033                     pSP[idx]->setComplex(true);
2034                     pSP[idx]->setCoef(&dblR, &dblI);
2035                 }
2036             }
2037             else
2038             {
2039                 double* pdblR = pIns->get();
2040                 SinglePoly** pSP = pP->get();
2041                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
2042                 {
2043                     double dblR = pdblR[idx];
2044                     pSP[idx]->setCoef(&dblR, NULL);
2045                 }
2046             }
2047
2048             pRet = pDest->insert(_pArgs, pP);
2049             pP->killMe();
2050         }
2051         else if (_pVar->isPoly() && _pInsert->isPoly())
2052         {
2053             pRet = _pVar->getAs<Polynom>()->insert(_pArgs, _pInsert);
2054         }
2055         else if (_pVar->isInt8() && _pInsert->isInt8())
2056         {
2057             pRet = _pVar->getAs<Int8>()->insert(_pArgs, _pInsert);
2058         }
2059         else if (_pVar->isUInt8() && _pInsert->isUInt8())
2060         {
2061             pRet = _pVar->getAs<UInt8>()->insert(_pArgs, _pInsert);
2062         }
2063         else if (_pVar->isInt16() && _pInsert->isInt16())
2064         {
2065             pRet = _pVar->getAs<Int16>()->insert(_pArgs, _pInsert);
2066         }
2067         else if (_pVar->isUInt16() && _pInsert->isUInt16())
2068         {
2069             pRet = _pVar->getAs<UInt16>()->insert(_pArgs, _pInsert);
2070         }
2071         else if (_pVar->isInt32() && _pInsert->isInt32())
2072         {
2073             pRet = _pVar->getAs<Int32>()->insert(_pArgs, _pInsert);
2074         }
2075         else if (_pVar->isUInt32() && _pInsert->isUInt32())
2076         {
2077             pRet = _pVar->getAs<UInt32>()->insert(_pArgs, _pInsert);
2078         }
2079         else if (_pVar->isInt64() && _pInsert->isInt64())
2080         {
2081             pRet = _pVar->getAs<Int64>()->insert(_pArgs, _pInsert);
2082         }
2083         else if (_pVar->isUInt64() && _pInsert->isUInt64())
2084         {
2085             pRet = _pVar->getAs<UInt64>()->insert(_pArgs, _pInsert);
2086         }
2087         else if (_pVar->isStruct())
2088         {
2089             Struct* pStruct = _pVar->getAs<Struct>();
2090             // insert something in a field of a struct
2091             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2092             {
2093                 //s("x") = y
2094                 String *pS = (*_pArgs)[0]->getAs<String>();
2095                 if (pS->isScalar() == false)
2096                 {
2097                     if (pIL)
2098                     {
2099                         pIL->killMe();
2100                     }
2101                     //manage error
2102                     std::wostringstream os;
2103                     os << _W("Invalid Index.\n");
2104                     throw ast::ScilabError(os.str(), 999, e.getLocation());
2105                 }
2106
2107                 if (_pInsert->isListDelete())
2108                 {
2109                     /* Remove a field */
2110                     pStruct->removeField(pS->get(0));
2111                 }
2112                 else
2113                 {
2114                     /* Add a field */
2115                     pStruct->addField(pS->get(0));
2116                     for (int i = 0; i < pStruct->getSize(); i++)
2117                     {
2118                         pStruct->get(i)->set(pS->get(0), _pInsert);
2119                     }
2120                 }
2121                 pRet = pStruct;
2122             }
2123             else // insert something in a struct
2124             {
2125                 if (_pInsert->isStruct())
2126                 {
2127                     String* pStrFieldsName = pStruct->getFieldNames();
2128                     Struct* pStructInsert = _pInsert->clone()->getAs<Struct>();
2129                     String* pStrInsertFieldsName = pStructInsert->getFieldNames();
2130                     Struct* pStructRet = NULL;
2131
2132                     // if not an empty struct
2133                     if (pStrFieldsName)
2134                     {
2135                         // insert fields of pStruct in pStructInsert
2136                         for (int i = pStrFieldsName->getSize(); i > 0; i--)
2137                         {
2138                             if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
2139                             {
2140                                 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
2141                             }
2142                             else
2143                             {
2144                                 std::wstring pwcsField = pStrFieldsName->get(i - 1);
2145                                 List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
2146
2147                                 for (int i = 0; i < pLExtract->getSize(); i++)
2148                                 {
2149                                     // protect element wich are not cloned before call removeField.
2150                                     pLExtract->get(i)->IncreaseRef();
2151                                 }
2152
2153                                 pStructInsert->removeField(pwcsField);
2154                                 pStructInsert->addFieldFront(pwcsField);
2155
2156                                 for (int i = 0; i < pLExtract->getSize(); i++)
2157                                 {
2158                                     // set elements in the new position
2159                                     pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
2160                                     pLExtract->get(i)->DecreaseRef();
2161                                 }
2162
2163                                 pLExtract->killMe();
2164                             }
2165                         }
2166
2167                         pStrFieldsName->killMe();
2168                     }
2169
2170                     // insert elements in following pArgs
2171                     pRet = pStruct->insert(_pArgs, pStructInsert);
2172                     pStructRet = pRet->getAs<Struct>();
2173
2174                     pStructInsert->killMe();
2175
2176                     // insert fields of pStructInsert in pRet
2177                     for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
2178                     {
2179                         if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
2180                         {
2181                             pStructRet->addField(pStrInsertFieldsName->get(i));
2182                         }
2183                     }
2184
2185                     pStrInsertFieldsName->killMe();
2186                 }
2187                 else
2188                 {
2189                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2190                 }
2191             }
2192         }
2193         else if (_pVar->isTList() || _pVar->isMList())
2194         {
2195             TList* pTL = _pVar->getAs<TList>();
2196             if (_pArgs->size() == 1)
2197             {
2198                 if ((*_pArgs)[0]->isString())
2199                 {
2200                     //s("x") = y
2201                     String *pS = (*_pArgs)[0]->getAs<String>();
2202                     if (pS->isScalar() == false)
2203                     {
2204                         if (pIL)
2205                         {
2206                             pIL->killMe();
2207                         }
2208
2209                         //manage error
2210                         std::wostringstream os;
2211                         os << _W("Invalid Index.\n");
2212                         throw ast::ScilabError(os.str(), 999, e.getLocation());
2213                     }
2214
2215                     if (_pInsert->isListDelete())
2216                     {
2217                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2218                     }
2219
2220                     if (pTL->exists(pS->get(0)))
2221                     {
2222                         pTL->set(pS->get(0), _pInsert);
2223                         pRet = pTL;
2224                     }
2225                     else
2226                     {
2227                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2228
2229                         //ExecVisitor exec;
2230                         //typed_list in;
2231                         //typed_list out;
2232                         //std::wstring function_name = L"%l_e";
2233
2234                         //_pInsert->IncreaseRef();
2235                         //in.push_back(_pInsert);
2236
2237                         //Overload::call(function_name, in, 1, out, &exec);
2238                         //_pInsert->DecreaseRef();
2239
2240                         //if (out.size() != 0)
2241                         //{
2242                         //    pRet = in[0];
2243                         //}
2244                     }
2245                 }
2246                 else
2247                 {
2248                     // s(x)
2249                     if (_pVar->isMList())
2250                     {
2251                         pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2252                     }
2253                     else
2254                     {
2255                         // In case where pTL is in several scilab variable,
2256                         // we have to clone it for keep the other variables unchanged.
2257                         if (pTL->getRef() > 1)
2258                         {
2259                             pTL = pTL->clone()->getAs<TList>();
2260                         }
2261
2262                         pRet = pTL->insert(_pArgs, _pInsert);
2263
2264                         // If we have inserted something else than a String
2265                         // in the first element, the TList have to be a List.
2266                         if (pTL->get(0)->isString() == false)
2267                         {
2268                             List* pL = new List();
2269                             for (int i = 0; i < pTL->getSize(); i++)
2270                             {
2271                                 pL->append(pTL->get(i));
2272                             }
2273
2274                             pTL->killMe();
2275                             pRet = pL;
2276                         }
2277                     }
2278                 }
2279             }
2280             else
2281             {
2282                 if (_pVar->isMList())
2283                 {
2284                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2285                 }
2286                 else
2287                 {
2288                     // call the overload if it exists.
2289                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2290                     if (pRet == NULL)
2291                     {
2292                         // else normal insert
2293                         pRet = pTL->insert(_pArgs, _pInsert);
2294                     }
2295                 }
2296             }
2297         }
2298         else if (_pVar->isList())
2299         {
2300             List* pL = NULL;
2301             // In case where pL is in several scilab variable,
2302             // we have to clone it for keep the other variables unchanged.
2303             if (_pVar->getRef() > 1)
2304             {
2305                 pL = _pVar->clone()->getAs<List>();
2306                 pRet = pL->insert(_pArgs, _pInsert);
2307                 if (pRet == NULL)
2308                 {
2309                     pL->killMe();
2310                     // call overload
2311                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2312                 }
2313             }
2314             else
2315             {
2316                 pL = _pVar->getAs<List>();
2317                 pRet = pL->insert(_pArgs, _pInsert);
2318                 if (pRet == NULL)
2319                 {
2320                     // call overload
2321                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2322                 }
2323             }
2324         }
2325         else if (_pVar->isHandle())
2326         {
2327             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2328             {
2329                 //s(["x"])
2330                 GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
2331                 String *pS = (*_pArgs)[0]->getAs<String>();
2332                 typed_list in;
2333                 typed_list out;
2334                 optional_list opt;
2335                 ast::ExecVisitor exec;
2336
2337                 in.push_back(pH);
2338                 in.push_back(pS);
2339                 in.push_back(_pInsert);
2340
2341                 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2342                 if (pCall)
2343                 {
2344                     Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
2345                     if (ret == Callable::OK)
2346                     {
2347                         pRet = _pVar;
2348                     }
2349                     else
2350                     {
2351                         throw ast::ScilabMessage();
2352                     }
2353                 }
2354             }
2355             else
2356             {
2357                 pRet = _pVar->getAs<GraphicHandle>()->insert(_pArgs, _pInsert);
2358             }
2359         }
2360         else if (_pVar->isUserType())
2361         {
2362             for (int i = 0; i < _pArgs->size(); i++)
2363             {
2364                 if ((*_pArgs)[i]->isImplicitList())
2365                 {
2366                     types::ImplicitList* pIL = (*_pArgs)[i]->getAs<types::ImplicitList>();
2367                     if (pIL->isComputable())
2368                     {
2369                         InternalType* pIT = pIL->extractFullMatrix();
2370                         (*_pArgs)[i]->killMe();
2371                         (*_pArgs)[i] = pIT;
2372                     }
2373                 }
2374             }
2375
2376             pRet = _pVar->getAs<UserType>()->insert(_pArgs, _pInsert);
2377             if (pRet == NULL)
2378             {
2379                 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2380             }
2381         }
2382         else if (_pVar->isCell())
2383         {
2384             if (_pInsert->isCell() == false)
2385             {
2386                 //manage error
2387                 std::wostringstream os;
2388                 os << _W("Wrong insertion: A Cell expected: use {...} instead of (...).\n");
2389                 throw ast::ScilabError(os.str(), 999, e.getLocation());
2390             }
2391         }
2392         else
2393         {
2394             // overload
2395             pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2396         }
2397
2398         pOut = pRet;
2399     }
2400
2401     if (pIL)
2402     {
2403         pIL->killMe();
2404     }
2405
2406     return pOut;
2407 }
2408
2409 void callOnPrompt(void)
2410 {
2411     static symbol::Variable* onPrompt = NULL;
2412
2413     if (onPrompt == NULL)
2414     {
2415         onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2416     }
2417
2418     InternalType* pOnPrompt = NULL;
2419     pOnPrompt = onPrompt->get();
2420     if (pOnPrompt != NULL && pOnPrompt->isCallable())
2421     {
2422         typed_list in;
2423         typed_list out;
2424         optional_list opt;
2425         ast::ExecVisitor execCall;
2426         pOnPrompt->getAs<Callable>()->call(in, opt, 1, out, &execCall);
2427     }
2428 }
2429
2430 List* getPropertyTree(ast::Exp* e, List* pList)
2431 {
2432
2433     //a.b
2434     ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(e);
2435     if (pVar)
2436     {
2437         pList->append(new String(pVar->getSymbol().getName().c_str()));
2438         return pList;
2439     }
2440
2441     //a(x).b
2442     ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(e);
2443     if (pCall)
2444     {
2445         pList = getPropertyTree(&pCall->getName(), pList);
2446         ast::ExecVisitor exec;
2447         ast::exps_t exps = pCall->getArgs();
2448         for (auto exp : exps)
2449         {
2450             try
2451             {
2452                 exp->accept(exec);
2453                 pList->append(exec.getResult());
2454                 exec.clearResult();
2455             }
2456             catch (ast::ScilabException e)
2457             {
2458                 throw e;
2459             }
2460         }
2461         return pList;
2462     }
2463
2464     //a.b.c
2465     ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(e);
2466     if (pField)
2467     {
2468         pList = getPropertyTree(pField->getHead(), pList);
2469         pList = getPropertyTree(pField->getTail(), pList);
2470         return pList;
2471     }
2472
2473     return pList;
2474 }
2475
2476 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2477 {
2478     ast::Exp* newTree = NULL;
2479     unsigned char *newast = NULL;
2480     ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2481     ast::DeserializeVisitor* d = NULL;
2482
2483     if (_msg.empty())
2484     {
2485         unsigned char* astbin = s->serialize();
2486         //call ocamlpro typer
2487         //char *newast = ocamlpro_typer(astbin);
2488         //free(astbin);
2489
2490         //for debug
2491         newast = astbin;
2492
2493         d = new ast::DeserializeVisitor(newast);
2494         newTree = d->deserialize();
2495     }
2496     else
2497     {
2498         std::wstring msgS(_msg + L" serialize");
2499         std::wstring msgD(_msg + L" deserialize");
2500
2501         Timer timer;
2502         timer.start();
2503         unsigned char* astbin = s->serialize();
2504         timer.check(msgS.c_str());
2505
2506         //call ocamlpro typer
2507         //char *newast = ocamlpro_typer(astbin);
2508         //free(astbin);
2509
2510         //for debug
2511         newast = astbin;
2512
2513         timer.start();
2514         d = new ast::DeserializeVisitor(newast);
2515         newTree = d->deserialize();
2516         timer.check(msgD.c_str());
2517     }
2518
2519     free(newast);
2520     delete s;
2521     delete d;
2522     return newTree;
2523 }