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