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