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