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