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