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