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