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