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