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