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