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