c0af272358800bdc0f79cde9ddc02341c5e37d8f
[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 (fields.back()->getArgs())
699         {
700             // a(x)(y)(z)
701             ExpHistory * pEHParent = fields.back();
702             ExpHistory * pEH = new ExpHistory(pEHParent, pCurrentArgs);
703             pEH->setLevel(pEHParent->getLevel() + 1);
704             pEH->setArgsOwner(true);
705             fields.push_back(pEH);
706         }
707         else
708         {
709             // a(x)
710             fields.back()->setArgs(pCurrentArgs);
711         }
712
713         if (pCell)
714         {
715             // a{x}
716             fields.back()->setCellExp();
717         }
718
719         return bErr;
720     }
721     else
722     {
723         return false;
724     }
725 }
726
727 types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fields, InternalType* _pAssignValue)
728 {
729     std::list<ExpHistory*> evalFields;
730
731     //*** get main variable ***//
732     std::list<ExpHistory*>::iterator iterFields = fields.begin();
733     ExpHistory* pFirstField = *iterFields;
734     InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->name_get());
735     if (pIT == NULL)
736     {
737         if (pFirstField->isCellExp())
738         {
739             // a{x}, where "a" doesn't exists
740             pIT = new Cell(1, 1);
741             symbol::Context::getInstance()->put(pFirstField->getExp()->stack_get(), pIT);
742         }
743         else if (fields.size() > 1)
744         {
745             // is a field exp
746             //"a" does not exist or it is another type, create it with size 1,1 and return it
747             //create new structure variable
748             pIT = new Struct(1, 1);
749             symbol::Context::getInstance()->put(pFirstField->getExp()->stack_get(), pIT);
750         }
751         // else
752         // is a call exp
753         // a(x) = "something" and a does not exist
754         // a will be create in insertionCall
755     }
756     else if (pIT->getRef() > 1 && pIT->isHandle() == false)
757     {
758         pIT = pIT->clone();
759         symbol::Context::getInstance()->put(pFirstField->getExp()->stack_get(), pIT);
760     }
761     else if (pIT == _pAssignValue)
762     {
763         // clone me before insert me in myself.
764         // ie : a.b = 2; a.b.c.d = a;
765         _pAssignValue = _pAssignValue->clone();
766     }
767
768     iterFields++;
769
770     std::list<ExpHistory*> workFields;
771     workFields.push_back(new ExpHistory(NULL,
772                                         pFirstField->getExp(),
773                                         pFirstField->getArgs(),
774                                         pFirstField->getLevel(),
775                                         pFirstField->isCellExp(),
776                                         pIT));
777
778     //*** evaluate fields ***//
779     while (iterFields != fields.end())
780     {
781         ExpHistory* pEH = workFields.front();
782         evalFields.push_back(pEH);
783         workFields.pop_front();
784
785         types::InternalType* pITCurrent = pEH->getCurrent();
786
787         if (pEH->isCellExp() && pITCurrent->isCell() == false)
788         {
789             std::wostringstream os;
790             os << _W("Wrong insertion : use extraction with {} only on a Cell.");
791             throw ast::ScilabError(os.str(), 999, _pExp->location_get());
792         }
793
794         if (pITCurrent->isStruct())
795         {
796             Struct* pStruct = pITCurrent->getAs<Struct>();
797             std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
798             int iSizeStuct = pStruct->getSize();
799
800             if (pEH->needResize())
801             {
802                 if (pEH->getArgsDims() == 1)
803                 {
804                     std::wostringstream os;
805                     os << _W("Invalid index.");
806                     throw ast::ScilabError(os.str(), 999, _pExp->location_get());
807                 }
808
809                 // resize current struct
810                 pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
811             }
812
813             // create field in parent if it not exist
814             if (pStruct->exists(pwcsFieldname) == false)
815             {
816                 pStruct->addField(pwcsFieldname);
817             }
818
819             if (pEH->getArgs())
820             {
821                 InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
822                 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
823             }
824             else
825             {
826                 // extract field x and append it to elements for next recursion.
827                 List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
828                 for (int iList = 0; iList < pLOut->getSize(); iList++)
829                 {
830                     InternalType* pIT = pLOut->get(iList);
831                     if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
832                     {
833                         // clone element before modify it.
834                         //pIT->DecreaseRef();
835                         pIT = pIT->clone();
836                         pStruct->get(iList)->set(pwcsFieldname, pIT);
837                     }
838
839                     ExpHistory* pEHChield = new ExpHistory( pEH,
840                                                             (*iterFields)->getExp(),
841                                                             (*iterFields)->getArgs(),
842                                                             (*iterFields)->getLevel(),
843                                                             (*iterFields)->isCellExp(),
844                                                             pIT);
845                     pEHChield->setWhereReinsert(iList);
846                     workFields.push_back(pEHChield);
847                 }
848
849                 delete pLOut;
850             }
851         }
852         else if (pITCurrent->isTList() || pITCurrent->isMList())
853         {
854             TList* pTL = pITCurrent->getAs<TList>();
855             typed_list* pArgs = pEH->getArgs();
856             if (pArgs && (*pArgs)[0]->isString() == false)
857             {
858                 if (pArgs->size() > 1 || pITCurrent->isMList())
859                 {
860                     // call overload
861                     InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
862                     if ((*iterFields)->getExp() == NULL)
863                     {
864                         // a(x)(y) => a.b(y)
865                         // extract a(x) and push_BACK to extract next level
866                         workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
867                         workFields.back()->setReinsertion();
868                     }
869                     else
870                     {
871                         // a(x).b
872                         // extract a(x) and push_FRONT to extract b from a(x)
873                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
874                         workFields.front()->setReinsertion();
875                     }
876                 }
877                 else
878                 {
879                     // resize TList
880                     int iNewSize = pEH->getSizeFromArgs();
881                     if (pTL->getSize() < iNewSize)
882                     {
883                         pTL->set(iNewSize - 1, new ListUndefined());
884                     }
885
886                     std::vector<InternalType*> vectpIT = pTL->extract(pArgs);
887                     std::vector<InternalType*>::iterator iterVect;
888                     double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
889                     int iLoop = 0;
890
891                     if ((*iterFields)->getExp() == NULL)
892                     {
893                         // a(x)(y) => a.b(y)
894                         // extract a(x) and push_BACK to extract next level
895                         for (iterVect = vectpIT.begin(); iterVect != vectpIT.end(); iterVect++, iLoop++)
896                         {
897                             ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), *iterVect);
898                             pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
899                             workFields.push_back(pEHExtract);
900                         }
901                     }
902                     else
903                     {
904                         // a(x).b
905                         // extract a(x) and push_FRONT to extract b from a(x)
906                         for (iterVect = vectpIT.begin(); iterVect != vectpIT.end(); iterVect++, iLoop++)
907                         {
908                             ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), *iterVect);
909                             pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
910                             workFields.push_front(pEHExtract);
911                         }
912                     }
913                 }
914             }
915             else
916             {
917                 // get string "x"
918                 InternalType* pExtract = NULL;
919                 std::wstring pwcsFieldname = L"";
920                 bool bReinsert = false;
921                 ExpHistory* pEHChield = NULL;
922
923                 if (pArgs)
924                 {
925                     // a('x')
926                     pwcsFieldname = (*pArgs)[0]->getAs<String>()->get(0);
927                 }
928                 else
929                 {
930                     // a.x
931                     pwcsFieldname = (*iterFields)->getExpAsString();
932                 }
933
934                 // check if field exists
935                 if (pTL->exists(pwcsFieldname) == false)
936                 {
937                     std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
938                     ++iterFieldsNext;
939
940                     if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
941                     {
942                         // M=mlist(['MType','x','y'], ...
943                         // M.rows1 = "somthing"
944                         if (pArgs == NULL)
945                         {
946                             pArgs = new typed_list();
947                             pArgs->push_back(new String(pwcsFieldname.c_str()));
948                         }
949
950                         // call overload
951                         pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
952                         bReinsert = true;
953
954                         if (pEH->getArgs() == NULL)
955                         {
956                             delete pArgs;
957                         }
958                     }
959                 }
960                 else
961                 {
962                     // extract field x and append it to elements for next recursion.
963                     pExtract = pTL->getField(pwcsFieldname);
964                 }
965
966                 // History management
967                 if (pEH->getArgs())
968                 {
969                     if ((*iterFields)->getExp() == NULL)
970                     {
971                         // a('x')(y) => a.b(y)
972                         // extract a(x) and push_BACK to extract next level
973                         pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
974                         workFields.push_back(pEHChield);
975                     }
976                     else
977                     {
978                         // a('x').b -> a('x')('b')
979                         // extract a(x) and push_FRONT to extract b from a(x)
980                         pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract);
981                         workFields.push_front(pEHChield);
982                     }
983                 }
984                 else
985                 {
986                     // a.x
987                     pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
988                     workFields.push_back(pEHChield);
989                 }
990
991                 if (bReinsert)
992                 {
993                     pEHChield->setReinsertion();
994                 }
995             }
996         }
997         else if (pITCurrent->isList())
998         {
999             List* pL = pITCurrent->getAs<List>();
1000             if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
1001             {
1002                 // pITCurrent is an extraction of other Type
1003                 for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
1004                 {
1005                     ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
1006                     pEHExtract->setWhereReinsert(iLoop);
1007                     workFields.push_front(pEHExtract);
1008                 }
1009             }
1010             else
1011             {
1012                 // pITCurrent is a field
1013                 if (pEH->getArgs())
1014                 {
1015                     if (pEH->getArgs()->size() > 1)
1016                     {
1017                         // call overload
1018                         InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
1019
1020                         if ((*iterFields)->getExp() == NULL)
1021                         {
1022                             // a(x)(y)
1023                             // extract a(x) and push_BACK to extract next level
1024                             workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1025                             workFields.back()->setReinsertion();
1026                         }
1027                         else
1028                         {
1029                             // a(x).b
1030                             // extract a(x) and push_FRONT to extract b from a(x)
1031                             workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1032                             workFields.front()->setReinsertion();
1033                         }
1034                     }
1035                     else
1036                     {
1037                         // resize List
1038                         int iNewSize = pEH->getSizeFromArgs();
1039                         if (pL->getSize() < iNewSize)
1040                         {
1041                             pL->set(iNewSize - 1, new ListUndefined());
1042                         }
1043
1044                         Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
1045                         double* pdblArgs = pDblArgs->get();
1046
1047                         if ((*iterFields)->getExp() == NULL)
1048                         {
1049                             // a(x)(y) => a.b(y)
1050                             // extract a(x) and push_BACK to extract next level
1051                             for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1052                             {
1053                                 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1054                                 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1055                                 workFields.push_back(pEHExtract);
1056                             }
1057                         }
1058                         else
1059                         {
1060                             // a(x).b
1061                             // extract a(x) and push_FRONT to extract b from a(x)
1062                             for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1063                             {
1064                                 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1065                                 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1066                                 workFields.push_front(pEHExtract);
1067                             }
1068                         }
1069                     }
1070                 }
1071                 else
1072                 {
1073                     // a.x, get string "x"
1074                     std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1075
1076                     // call overload
1077                     typed_list* args = new typed_list();
1078                     args->push_back(new String(pwcsFieldname.c_str()));
1079                     pEH->setArgs(args);
1080
1081                     InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
1082
1083                     // append extraction of a.x for next level.
1084                     workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1085                     workFields.back()->setReinsertion();
1086                 }
1087             }
1088         }
1089         else if (pITCurrent->isHandle())
1090         {
1091             // call overload
1092             if (pEH->getArgs())
1093             {
1094                 // call overload
1095                 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1096
1097                 if ((*iterFields)->getExp() == NULL)
1098                 {
1099                     // a(x)(y)
1100                     // extract a(x) and push_BACK to extract next level
1101                     workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1102                     workFields.back()->setReinsertion();
1103                 }
1104                 else
1105                 {
1106                     // a(x).b
1107                     // extract a(x) and push_FRONT to extract b from a(x)
1108                     workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1109                     workFields.front()->setReinsertion();
1110                 }
1111             }
1112             else
1113             {
1114                 // a.x, get string "x"
1115                 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1116
1117                 // create arg with next field
1118                 typed_list* args = new typed_list();
1119                 args->push_back(new String(pwcsFieldname.c_str()));
1120                 pEH->setArgs(args);
1121
1122                 // call overload
1123                 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1124
1125                 // append extraction of a.x for next level.
1126                 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1127                 workFields.front()->setReinsertion();
1128             }
1129         }
1130         else if (pITCurrent->isCell())
1131         {
1132             Cell* pCell = pITCurrent->getAs<Cell>();
1133             if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
1134             {
1135                 if (pEH->isCellExp())
1136                 {
1137                     // a{x} => extract like a(x){[1 2 ...]}
1138                     if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
1139                     {
1140                         // extract each elements of a(x)
1141                         for (int iCell = 0; iCell < pCell->getSize(); iCell++)
1142                         {
1143                             InternalType* pIT = pCell->get(iCell);
1144                             if ((*iterFields)->getExp() == NULL)
1145                             {
1146                                 // a{x}(y)
1147                                 ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
1148                                 pEHChield->setWhereReinsert(iCell);
1149                                 workFields.push_back(pEHChield);
1150                             }
1151                             else
1152                             {
1153                                 // a{x}.b
1154                                 ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
1155                                 pEHChield->setWhereReinsert(iCell);
1156                                 workFields.push_front(pEHChield);
1157                             }
1158                         }
1159                     }
1160                     else
1161                     {
1162                         if (pEH->needResize())
1163                         {
1164                             if (pEH->getArgsDims() == 1)
1165                             {
1166                                 std::wostringstream os;
1167                                 os << _W("Invalid index.");
1168                                 throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1169                             }
1170
1171                             // resize current Cell
1172                             pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1173                         }
1174
1175                         InternalType* pIT = pCell->extract(pEH->getArgs());
1176                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
1177                         workFields.front()->setReinsertion();
1178                     }
1179                 }
1180                 else
1181                 {
1182                     if ((*iterFields)->isCellExp())
1183                     {
1184                         // a(x){y}
1185                         if (pEH->needResize())
1186                         {
1187                             if (pEH->getArgsDims() == 1)
1188                             {
1189                                 std::wostringstream os;
1190                                 os << _W("Invalid index.");
1191                                 throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1192                             }
1193
1194                             // resize current Cell
1195                             pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1196                         }
1197
1198                         InternalType* pIT = pCell->extract(pEH->getArgs());
1199                         workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
1200                         workFields.front()->setReinsertion();
1201                     }
1202                     else
1203                     {
1204                         // only a(x)
1205                         std::wostringstream os;
1206                         os << _W("Wrong insertion in a Cell.");
1207                         throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1208                     }
1209                 }
1210             }
1211             else
1212             {
1213                 std::wostringstream os;
1214                 os << _W("Wrong insertion in a Cell.");
1215                 throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1216             }
1217         }
1218         else if (pITCurrent == 0) // implicit struct creation
1219         {
1220             InternalType* pIT = new Struct(1, 1);
1221             pEH->setCurrent(pIT);
1222             pEH->setReinsertion();
1223
1224             workFields.push_front(pEH);
1225             evalFields.pop_back();
1226         }
1227         else // not a Scilab defined datatype, access field after field
1228         {
1229             typed_list* pArgs = pEH->getArgs();
1230
1231             // get string "x"
1232             std::wstring pwcsFieldname = L"";
1233             ExpHistory* pEHChield = 0;
1234
1235             if (pArgs)
1236             {
1237                 // a('x')
1238                 pwcsFieldname = (*pArgs)[0]->getAs<String>()->get(0);
1239             }
1240             else
1241             {
1242                 // a.x
1243                 pwcsFieldname = (*iterFields)->getExpAsString();
1244             }
1245
1246             // History management
1247             if (pArgs)
1248             {
1249                 if ((*iterFields)->getExp() == NULL)
1250                 {
1251                     // a('x')(y) => a.b(y)
1252                     // extract a(x) and push_BACK to extract next level
1253                     pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), 0);
1254                     workFields.push_back(pEHChield);
1255                 }
1256                 else
1257                 {
1258                     // a('x').b -> a('x')('b')
1259                     // extract a(x) and push_FRONT to extract b from a(x)
1260                     pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), 0);
1261                     workFields.push_front(pEHChield);
1262                 }
1263             }
1264             else
1265             {
1266                 // a.x
1267                 pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), 0);
1268                 workFields.push_back(pEHChield);
1269             }
1270         }
1271
1272         if (workFields.front()->getLevel() == (*iterFields)->getLevel())
1273         {
1274             // go to next field
1275             iterFields++;
1276         }
1277     }
1278
1279     //*** insert what we have to assign ***//
1280     while (workFields.empty() == false)
1281     {
1282         ExpHistory* pEH = workFields.front();
1283         evalFields.push_back(pEH);
1284         workFields.pop_front();
1285
1286         if (pEH->getArgs())
1287         {
1288             typed_list* pArgs = pEH->getArgs();
1289             if (pEH->isCellExp())
1290             {
1291                 Cell* pCell = pEH->getCurrent()->getAs<Cell>();
1292                 // insert "something" in b{x}
1293                 if ((*pArgs)[0]->isString())
1294                 {
1295                     std::wostringstream os;
1296                     os << _W("Wrong insertion in a Cell.");
1297                     throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1298                 }
1299
1300                 pCell->insertCell(pArgs, _pAssignValue);
1301             }
1302             else
1303             {
1304                 // insert "something" in b(x,y)
1305                 InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
1306                 if (pIT == NULL)
1307                 {
1308                     std::wostringstream os;
1309                     os << _W("Error in insertion of Struct.");
1310                     throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1311                 }
1312
1313                 if (pEH->setCurrent(pIT))
1314                 {
1315                     pEH->setReinsertion();
1316                 }
1317             }
1318         }
1319         else
1320         {
1321             InternalType* pParent = pEH->getParent()->getCurrent();
1322             if (pParent->isStruct())
1323             {
1324                 Struct* pStruct = pParent->getAs<Struct>();
1325                 if (_pAssignValue->isListDelete())
1326                 {
1327                     pStruct->removeField(pEH->getExpAsString());
1328                 }
1329                 else
1330                 {
1331                     pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), _pAssignValue);
1332                 }
1333             }
1334             else if (pParent->isTList() || pParent->isMList())
1335             {
1336                 TList* pTL = pParent->getAs<TList>();
1337                 if (_pAssignValue->isListDelete() || (pTL->exists(pEH->getExpAsString()) == false))
1338                 {
1339                     typed_list args;
1340                     args.push_back(new String(pEH->getExpAsString().c_str()));
1341                     InternalType* pIT = insertionCall(*_pExp, &args, pEH->getParent()->getCurrent(), _pAssignValue);
1342                     if (pIT == NULL)
1343                     {
1344                         std::wostringstream os;
1345                         os << _W("Error in insertion of TList.");
1346                         throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1347                     }
1348
1349                     if (pEH->getParent()->setCurrent(pIT))
1350                     {
1351                         pEH->getParent()->setReinsertion();
1352                         pEH->resetReinsertion();
1353                     }
1354                 }
1355                 else
1356                 {
1357                     pTL->set(pEH->getExpAsString(), _pAssignValue);
1358                 }
1359             }
1360             else
1361             {
1362                 pEH->setCurrent(_pAssignValue);
1363                 pEH->setReinsertion();
1364             }
1365         }
1366     }
1367
1368     //*** update fields ***//
1369     while (evalFields.empty() == false)
1370     {
1371         ExpHistory* pEH = evalFields.back();
1372         if (pEH->reinsertMe())
1373         {
1374             ExpHistory* pEHParent = pEH->getParent();
1375
1376             if (pEHParent == NULL)
1377             {
1378                 symbol::Context::getInstance()->put(pEH->getExp()->stack_get(), pEH->getCurrent());
1379                 break;
1380             }
1381
1382             typed_list* pParentArgs = pEHParent->getArgs();
1383             if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
1384             {
1385                 InternalType* pParent = pEHParent->getCurrent();
1386                 if (pParent->isStruct())
1387                 {
1388                     Struct* pStruct = pParent->getAs<Struct>();
1389                     pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
1390                     evalFields.pop_back();
1391                     delete pEH;
1392                     continue;
1393                 }
1394                 else if (pParent->isTList() || pParent->isMList())
1395                 {
1396                     TList* pTL = pParent->getAs<TList>();
1397                     if (pParentArgs)
1398                     {
1399                         pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
1400                         evalFields.pop_back();
1401                         delete pEH;
1402                         continue;
1403                     }
1404                     else
1405                     {
1406                         if (pTL->exists(pEH->getExpAsString()))
1407                         {
1408                             pTL->set(pEH->getExpAsString(), pEH->getCurrent());
1409                             evalFields.pop_back();
1410                             delete pEH;
1411                             continue;
1412                         }
1413
1414                         pParentArgs = new typed_list();
1415                         pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
1416                     }
1417                 }
1418                 else if (pParent->isCell())
1419                 {
1420                     Cell* pCell = pParent->getAs<Cell>();
1421                     if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
1422                     {
1423                         // a{x}.b => reinsert b in a{x}
1424                         pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
1425                         pEHParent->setReinsertion();
1426                         evalFields.pop_back();
1427                         delete pEH;
1428                         continue;
1429                     }
1430                 }
1431                 else
1432                 {
1433                     pParentArgs = new typed_list();
1434                     pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
1435                 }
1436             }
1437
1438             InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
1439             if (pIT == NULL)
1440             {
1441                 std::wostringstream os;
1442                 os << _W("Error in insertion of Struct.");
1443                 throw ast::ScilabError(os.str(), 999, _pExp->location_get());
1444             }
1445
1446             if (pEHParent->setCurrent(pIT))
1447             {
1448                 pEHParent->setReinsertion();
1449             }
1450
1451             if (pEHParent->getArgs() == NULL)
1452             {
1453                 delete pParentArgs;
1454             }
1455         }
1456
1457         evalFields.pop_back();
1458         delete pEH;
1459     }
1460
1461     if (!evalFields.empty())
1462     {
1463         for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
1464         {
1465             delete *i;
1466         }
1467     }
1468
1469     return symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->name_get());
1470 }
1471
1472 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
1473 {
1474     InternalType* pOut = NULL;
1475     InternalType *pIL = NULL;
1476     //fisrt extract implicit list
1477     if (_pInsert->isColon())
1478     {
1479         //double* pdbl = NULL;
1480         //_pInsert = new Double(-1, -1, &pdbl);
1481         //pdbl[0] = 1;
1482         pIL = Double::Identity(-1, -1);
1483         _pInsert = pIL;
1484     }
1485     else if (_pInsert->isImplicitList())
1486     {
1487         pIL = _pInsert->getAs<ImplicitList>()->extractFullMatrix();
1488         if (pIL && pIL->isDeletable())
1489         {
1490             _pInsert = pIL;
1491         }
1492     }
1493     else if (_pInsert->isContainer() && _pInsert->isRef())
1494     {
1495         //std::cout << "assign container type during insertion" << std::endl;
1496         //InternalType* pIL = _pInsert->clone();
1497         //_pInsert = pIL;
1498     }
1499
1500     if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar == NULL)
1501     {
1502         // l(x) = [] when l is not defined => create l = []
1503         pOut = Double::Empty();
1504     }
1505     else if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1506     {
1507         //insert [] so deletion except for Struct and List which can insert []
1508         if (_pVar->isDouble())
1509         {
1510             pOut = _pVar->getAs<Double>()->remove(_pArgs);
1511         }
1512         else if (_pVar->isString())
1513         {
1514             pOut = _pVar->getAs<String>()->remove(_pArgs);
1515         }
1516         else if (_pVar->isCell())
1517         {
1518             pOut = _pVar->getAs<Cell>()->remove(_pArgs);
1519         }
1520         else if (_pVar->isBool())
1521         {
1522             pOut = _pVar->getAs<Bool>()->remove(_pArgs);
1523         }
1524         else if (_pVar->isPoly())
1525         {
1526             pOut = _pVar->getAs<Polynom>()->remove(_pArgs);
1527         }
1528         else if (_pVar->isInt8())
1529         {
1530             pOut = _pVar->getAs<Int8>()->remove(_pArgs);
1531         }
1532         else if (_pVar->isUInt8())
1533         {
1534             pOut = _pVar->getAs<UInt8>()->remove(_pArgs);
1535         }
1536         else if (_pVar->isInt16())
1537         {
1538             pOut = _pVar->getAs<Int16>()->remove(_pArgs);
1539         }
1540         else if (_pVar->isUInt16())
1541         {
1542             pOut = _pVar->getAs<UInt16>()->remove(_pArgs);
1543         }
1544         else if (_pVar->isInt32())
1545         {
1546             pOut = _pVar->getAs<Int32>()->remove(_pArgs);
1547         }
1548         else if (_pVar->isUInt32())
1549         {
1550             pOut = _pVar->getAs<UInt32>()->remove(_pArgs);
1551         }
1552         else if (_pVar->isInt64())
1553         {
1554             pOut = _pVar->getAs<Int64>()->remove(_pArgs);
1555         }
1556         else if (_pVar->isUInt64())
1557         {
1558             pOut = _pVar->getAs<UInt64>()->remove(_pArgs);
1559         }
1560         else if (_pVar->isStruct())
1561         {
1562             // a("b") = [] is not a deletion !!
1563             Struct* pStr = _pVar->getAs<Struct>();
1564
1565             pOut = _pVar->getAs<Struct>()->insert(_pArgs, _pInsert);
1566         }
1567         else if (_pVar->isHandle())
1568         {
1569             InternalType* pRet = NULL;
1570
1571             types::GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
1572             types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1573
1574             typed_list in;
1575             typed_list out;
1576             optional_list opt;
1577             ast::ExecVisitor exec;
1578
1579             in.push_back(pH);
1580             in.push_back(pS);
1581             in.push_back(_pInsert);
1582
1583             Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1584             Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, &exec);
1585             if (ret == Callable::OK)
1586             {
1587                 pRet = _pVar;
1588             }
1589             pOut = pRet;
1590         }
1591     }
1592     else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<Double>()->getSize() == 0))
1593     {
1594         //insert in a new variable or []
1595         //call static insert function
1596         //if _pVar == NULL and pArg is single string, it's a struct creation
1597         if ((*_pArgs)[0]->isString())
1598         {
1599             String *pS = (*_pArgs)[0]->getAs<types::String>();
1600             Struct* pStr = new Struct(1, 1);
1601
1602             if (_pArgs->size() != 1 || pS->isScalar() == false)
1603             {
1604                 if (pIL)
1605                 {
1606                     pIL->killMe();
1607                 }
1608                 //manage error
1609                 std::wostringstream os;
1610                 os << _W("Invalid Index.\n");
1611                 throw ast::ScilabError(os.str(), 999, e.location_get());
1612             }
1613
1614             pStr->addField(pS->get(0));
1615             pStr->get(0)->set(pS->get(0), _pInsert);
1616             pOut = pStr;
1617         }
1618         else
1619         {
1620             switch (_pInsert->getType())
1621             {
1622                 case InternalType::ScilabDouble :
1623                     pOut = Double::insertNew(_pArgs, _pInsert);
1624                     break;
1625                 case InternalType::ScilabString :
1626                     pOut = String::insertNew(_pArgs, _pInsert);
1627                     break;
1628                 case InternalType::ScilabCell :
1629                     pOut = Cell::insertNew(_pArgs, _pInsert);
1630                     break;
1631                 case InternalType::ScilabBool :
1632                     pOut = Bool::insertNew(_pArgs, _pInsert);
1633                     break;
1634                 case InternalType::ScilabPolynom :
1635                     pOut = Polynom::insertNew(_pArgs, _pInsert);
1636                     break;
1637                 case InternalType::ScilabInt8 :
1638                     pOut = Int8::insertNew(_pArgs, _pInsert);
1639                     break;
1640                 case InternalType::ScilabUInt8 :
1641                     pOut = UInt8::insertNew(_pArgs, _pInsert);
1642                     break;
1643                 case InternalType::ScilabInt16 :
1644                     pOut = Int16::insertNew(_pArgs, _pInsert);
1645                     break;
1646                 case InternalType::ScilabUInt16 :
1647                     pOut = UInt16::insertNew(_pArgs, _pInsert);
1648                     break;
1649                 case InternalType::ScilabInt32 :
1650                     pOut = Int32::insertNew(_pArgs, _pInsert);
1651                     break;
1652                 case InternalType::ScilabUInt32 :
1653                     pOut = UInt32::insertNew(_pArgs, _pInsert);
1654                     break;
1655                 case InternalType::ScilabInt64 :
1656                     pOut = Int64::insertNew(_pArgs, _pInsert);
1657                     break;
1658                 case InternalType::ScilabUInt64 :
1659                     pOut = UInt64::insertNew(_pArgs, _pInsert);
1660                     break;
1661                 case InternalType::ScilabSparse :
1662                     pOut = Sparse::insertNew(_pArgs, _pInsert);
1663                     break;
1664                 case InternalType::ScilabSparseBool :
1665                     pOut = SparseBool::insertNew(_pArgs, _pInsert);
1666                     break;
1667                 default :
1668                 {
1669                     // overload
1670                     types::Double* pEmpty = types::Double::Empty();
1671                     pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1672                     delete pEmpty;
1673                     break;
1674                 }
1675             }
1676         }
1677     }
1678     else
1679     {
1680         //call type insert function
1681         InternalType* pRet = NULL;
1682
1683         //check types compatibilties
1684         if (_pVar->isDouble() && _pInsert->isDouble())
1685         {
1686             pRet = _pVar->getAs<Double>()->insert(_pArgs, _pInsert);
1687         }
1688         else if (_pVar->isDouble() && _pInsert->isSparse())
1689         {
1690             Sparse* pSp = _pInsert->getAs<Sparse>();
1691             Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1692             pSp->fill(*pD);
1693             pRet = _pVar->getAs<Double>()->insert(_pArgs, pD);
1694             free(pD);
1695         }
1696         else if (_pVar->isString() && _pInsert->isString())
1697         {
1698             pRet = _pVar->getAs<String>()->insert(_pArgs, _pInsert);
1699         }
1700         else if (_pVar->isCell() && _pInsert->isCell())
1701         {
1702             pRet = _pVar->getAs<Cell>()->insert(_pArgs, _pInsert);
1703         }
1704         else if (_pVar->isBool() && _pInsert->isBool())
1705         {
1706             pRet = _pVar->getAs<Bool>()->insert(_pArgs, _pInsert);
1707         }
1708         else if (_pVar->isSparse() && _pInsert->isSparse())
1709         {
1710             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert->getAs<Sparse>());
1711         }
1712         else if (_pVar->isSparse() && _pInsert->isDouble())
1713         {
1714             pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert);
1715         }
1716         else if (_pVar->isSparseBool() && _pInsert->isSparseBool())
1717         {
1718             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert->getAs<SparseBool>());
1719         }
1720         else if (_pVar->isSparseBool() && _pInsert->isBool())
1721         {
1722             pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert);
1723         }
1724         else if (_pVar->isDouble() && _pInsert->isPoly())
1725         {
1726             Double* pDest = _pVar->getAs<Double>();
1727             Polynom* pIns = _pInsert->getAs<Polynom>();
1728             int iSize = pDest->getSize();
1729             int* piRanks = new int[iSize];
1730             memset(piRanks, 0x00, iSize * sizeof(int));
1731             Polynom* pP = new Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1732             delete[] piRanks;
1733             pP->setComplex(pDest->isComplex());
1734
1735             if (pP->isComplex())
1736             {
1737                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1738                 {
1739                     double dblR = pDest->get(idx);
1740                     double dblI = pDest->getImg(idx);
1741                     pP->get(idx)->setCoef(&dblR, &dblI);
1742                 }
1743             }
1744             else
1745             {
1746                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1747                 {
1748                     double dblR = pDest->get(idx);
1749                     pP->get(idx)->setCoef(&dblR, NULL);
1750                 }
1751             }
1752
1753             pRet = pP->insert(_pArgs, pIns);
1754             pDest->DecreaseRef();
1755         }
1756         else if (_pVar->isPoly() && _pInsert->isDouble())
1757         {
1758             Polynom* pDest = _pVar->getAs<Polynom>();
1759             Double* pIns = _pInsert->getAs<Double>();
1760             int iSize = pIns->getSize();
1761             int* piRanks = new int[iSize];
1762             memset(piRanks, 0x00, iSize * sizeof(int));
1763             Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
1764             delete[] piRanks;
1765             pP->setComplex(pIns->isComplex());
1766
1767             if (pP->isComplex())
1768             {
1769                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1770                 {
1771                     double dblR = pIns->get(idx);
1772                     double dblI = pIns->getImg(idx);
1773                     pP->get(idx)->setCoef(&dblR, &dblI);
1774                 }
1775             }
1776             else
1777             {
1778                 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1779                 {
1780                     double dblR = pIns->get(idx);
1781                     pP->get(idx)->setCoef(&dblR, NULL);
1782                 }
1783             }
1784
1785             pRet = pDest->insert(_pArgs, pP);
1786             delete pP;
1787         }
1788         else if (_pVar->isPoly() && _pInsert->isPoly())
1789         {
1790             pRet = _pVar->getAs<Polynom>()->insert(_pArgs, _pInsert);
1791         }
1792         else if (_pVar->isInt8() && _pInsert->isInt8())
1793         {
1794             pRet = _pVar->getAs<Int8>()->insert(_pArgs, _pInsert);
1795         }
1796         else if (_pVar->isUInt8() && _pInsert->isUInt8())
1797         {
1798             pRet = _pVar->getAs<UInt8>()->insert(_pArgs, _pInsert);
1799         }
1800         else if (_pVar->isInt16() && _pInsert->isInt16())
1801         {
1802             pRet = _pVar->getAs<Int16>()->insert(_pArgs, _pInsert);
1803         }
1804         else if (_pVar->isUInt16() && _pInsert->isUInt16())
1805         {
1806             pRet = _pVar->getAs<UInt16>()->insert(_pArgs, _pInsert);
1807         }
1808         else if (_pVar->isInt32() && _pInsert->isInt32())
1809         {
1810             pRet = _pVar->getAs<Int32>()->insert(_pArgs, _pInsert);
1811         }
1812         else if (_pVar->isUInt32() && _pInsert->isUInt32())
1813         {
1814             pRet = _pVar->getAs<UInt32>()->insert(_pArgs, _pInsert);
1815         }
1816         else if (_pVar->isInt64() && _pInsert->isInt64())
1817         {
1818             pRet = _pVar->getAs<Int64>()->insert(_pArgs, _pInsert);
1819         }
1820         else if (_pVar->isUInt64() && _pInsert->isUInt64())
1821         {
1822             pRet = _pVar->getAs<UInt64>()->insert(_pArgs, _pInsert);
1823         }
1824         else if (_pVar->isStruct())
1825         {
1826             Struct* pStruct = _pVar->getAs<Struct>();
1827             // insert something in a field of a struct
1828             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
1829             {
1830                 //s("x") = y
1831                 String *pS = (*_pArgs)[0]->getAs<types::String>();
1832                 if (pS->isScalar() == false)
1833                 {
1834                     if (pIL)
1835                     {
1836                         pIL->killMe();
1837                     }
1838                     //manage error
1839                     std::wostringstream os;
1840                     os << _W("Invalid Index.\n");
1841                     throw ast::ScilabError(os.str(), 999, e.location_get());
1842                 }
1843
1844                 pStruct->addField(pS->get(0));
1845                 for (int i = 0; i < pStruct->getSize(); i++)
1846                 {
1847                     pStruct->get(i)->set(pS->get(0), _pInsert);
1848                 }
1849
1850                 pRet = pStruct;
1851             }
1852             else // insert something in a struct
1853             {
1854                 if (_pInsert->isStruct())
1855                 {
1856                     String* pStrFieldsName = pStruct->getFieldNames();
1857                     Struct* pStructInsert = _pInsert->clone()->getAs<Struct>();
1858                     String* pStrInsertFieldsName = pStructInsert->getFieldNames();
1859                     Struct* pStructRet = NULL;
1860
1861                     // if not an empty struct
1862                     if (pStrFieldsName)
1863                     {
1864                         // insert fields of pStruct in pStructInsert
1865                         for (int i = pStrFieldsName->getSize(); i > 0; i--)
1866                         {
1867                             if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
1868                             {
1869                                 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
1870                             }
1871                             else
1872                             {
1873                                 std::wstring pwcsField = pStrFieldsName->get(i - 1);
1874                                 List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
1875
1876                                 for (int i = 0; i < pLExtract->getSize(); i++)
1877                                 {
1878                                     // protect element wich are not cloned before call removeField.
1879                                     pLExtract->get(i)->IncreaseRef();
1880                                 }
1881
1882                                 pStructInsert->removeField(pwcsField);
1883                                 pStructInsert->addFieldFront(pwcsField);
1884
1885                                 for (int i = 0; i < pLExtract->getSize(); i++)
1886                                 {
1887                                     // set elements in the new position
1888                                     pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
1889                                 }
1890                             }
1891                         }
1892                     }
1893
1894                     // insert elements in following pArgs
1895                     pRet = pStruct->insert(_pArgs, pStructInsert);
1896                     pStructRet = pRet->getAs<Struct>();
1897
1898                     // insert fields of pStructInsert in pRet
1899                     for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
1900                     {
1901                         if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
1902                         {
1903                             pStructRet->addField(pStrInsertFieldsName->get(i));
1904                         }
1905                     }
1906                 }
1907                 else
1908                 {
1909                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1910                 }
1911             }
1912         }
1913         else if (_pVar->isTList() || _pVar->isMList())
1914         {
1915             TList* pTL = _pVar->getAs<TList>();
1916             if (_pArgs->size() == 1)
1917             {
1918                 if ((*_pArgs)[0]->isString())
1919                 {
1920                     //s("x") = y
1921                     String *pS = (*_pArgs)[0]->getAs<types::String>();
1922                     if (pS->isScalar() == false)
1923                     {
1924                         if (pIL)
1925                         {
1926                             pIL->killMe();
1927                         }
1928
1929                         //manage error
1930                         std::wostringstream os;
1931                         os << _W("Invalid Index.\n");
1932                         throw ast::ScilabError(os.str(), 999, e.location_get());
1933                     }
1934
1935                     if (_pInsert->isListDelete())
1936                     {
1937                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1938                     }
1939
1940                     if (pTL->exists(pS->get(0)))
1941                     {
1942                         pTL->set(pS->get(0), _pInsert);
1943                         pRet = pTL;
1944                     }
1945                     else
1946                     {
1947                         return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1948
1949                         //ExecVisitor exec;
1950                         //types::typed_list in;
1951                         //types::typed_list out;
1952                         //std::wstring function_name = L"%l_e";
1953
1954                         //_pInsert->IncreaseRef();
1955                         //in.push_back(_pInsert);
1956
1957                         //Overload::call(function_name, in, 1, out, &exec);
1958                         //_pInsert->DecreaseRef();
1959
1960                         //if (out.size() != 0)
1961                         //{
1962                         //    pRet = in[0];
1963                         //}
1964                     }
1965                 }
1966                 else
1967                 {
1968                     // s(x)
1969                     if (_pVar->isMList())
1970                     {
1971                         pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1972                     }
1973                     else
1974                     {
1975                         pRet = pTL->insert(_pArgs, _pInsert);
1976                     }
1977                 }
1978             }
1979             else
1980             {
1981                 if (_pVar->isMList())
1982                 {
1983                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1984                 }
1985                 else
1986                 {
1987                     // call the overload if it exists.
1988                     pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1989                     if (pRet == NULL)
1990                     {
1991                         // else normal insert
1992                         pRet = pTL->insert(_pArgs, _pInsert);
1993                     }
1994                 }
1995             }
1996         }
1997         else if (_pVar->isList())
1998         {
1999             pRet = _pVar->getAs<List>()->insert(_pArgs, _pInsert);
2000             if (pRet == NULL)
2001             {
2002                 // call overload
2003                 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2004             }
2005         }
2006         else if (_pVar->isHandle())
2007         {
2008             if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2009             {
2010                 //s(["x"])
2011                 types::GraphicHandle* pH = _pVar->getAs<types::GraphicHandle>();
2012                 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
2013                 typed_list in;
2014                 typed_list out;
2015                 optional_list opt;
2016                 ast::ExecVisitor exec;
2017
2018                 in.push_back(pH);
2019                 in.push_back(pS);
2020                 in.push_back(_pInsert);
2021
2022                 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2023                 if (pCall)
2024                 {
2025                     Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, &exec);
2026                     if (ret == Callable::OK)
2027                     {
2028                         pRet = _pVar;
2029                     }
2030                 }
2031             }
2032             else
2033             {
2034                 pRet = _pVar->getAs<types::GraphicHandle>()->extract(_pArgs);
2035             }
2036         }
2037         else
2038         {
2039             // overload
2040             pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2041         }
2042
2043         pOut = pRet;
2044     }
2045
2046     if (pIL)
2047     {
2048         pIL->killMe();
2049     }
2050
2051     return pOut;
2052 }
2053
2054 void callOnPrompt(void)
2055 {
2056     static symbol::Variable* onPrompt = NULL;
2057
2058     if (onPrompt == NULL)
2059     {
2060         onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2061     }
2062
2063     types::InternalType* pOnPrompt = NULL;
2064     pOnPrompt = onPrompt->get();
2065     if (pOnPrompt != NULL && pOnPrompt->isCallable())
2066     {
2067         types::typed_list in;
2068         types::typed_list out;
2069         types::optional_list opt;
2070         ast::ExecVisitor execCall;
2071         pOnPrompt->getAs<types::Callable>()->call(in, opt, 1, out, &execCall);
2072     }
2073 }
2074
2075 List* getPropertyTree(ast::Exp* e, List* pList)
2076 {
2077
2078     //a.b
2079     ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(e);
2080     if (pVar)
2081     {
2082         pList->append(new String(pVar->name_get().name_get().c_str()));
2083         return pList;
2084     }
2085
2086     //a(x).b
2087     ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(e);
2088     if (pCall)
2089     {
2090         pList = getPropertyTree(&pCall->name_get(), pList);
2091         ast::ExecVisitor exec;
2092         std::list<ast::Exp*> l = pCall->args_get();
2093         std::list<ast::Exp*>::const_iterator it;
2094         for (it = l.begin() ; it != l.end() ; it++)
2095         {
2096             ast::Exp* pArg = (*it);
2097             try
2098             {
2099                 pArg->accept(exec);
2100                 pList->append(exec.result_get());
2101                 exec.result_clear();
2102             }
2103             catch (ast::ScilabException e)
2104             {
2105                 throw e;
2106             }
2107         }
2108
2109         return pList;
2110     }
2111
2112     //a.b.c
2113     ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(e);
2114     if (pField)
2115     {
2116         pList = getPropertyTree(pField->head_get(), pList);
2117         pList = getPropertyTree(pField->tail_get(), pList);
2118         return pList;
2119     }
2120
2121     return pList;
2122 }
2123
2124 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2125 {
2126     ast::Exp* newTree = NULL;
2127     unsigned char *newast = NULL;
2128     ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2129     ast::DeserializeVisitor* d = NULL;
2130
2131     if (_msg.empty())
2132     {
2133         unsigned char* astbin = s->serialize();
2134         //call ocamlpro typer
2135         //char *newast = ocamlpro_typer(astbin);
2136         //free(astbin);
2137
2138         //for debug
2139         newast = astbin;
2140
2141         d = new ast::DeserializeVisitor(newast);
2142         newTree = d->deserialize();
2143     }
2144     else
2145     {
2146         std::wstring msgS(_msg + L" serialize");
2147         std::wstring msgD(_msg + L" deserialize");
2148
2149         Timer timer;
2150         timer.start();
2151         unsigned char* astbin = s->serialize();
2152         timer.check(msgS.c_str());
2153
2154         //call ocamlpro typer
2155         //char *newast = ocamlpro_typer(astbin);
2156         //free(astbin);
2157
2158         //for debug
2159         newast = astbin;
2160
2161         timer.start();
2162         d = new ast::DeserializeVisitor(newast);
2163         newTree = d->deserialize();
2164         timer.check(msgD.c_str());
2165     }
2166
2167     free(newast);
2168     delete s;
2169     delete d;
2170     return newTree;
2171 }