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