cosmetic, rename functions
[scilab.git] / scilab / modules / ast / includes / run_AssignExp.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2008-2008 - 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 // This code is separated in run_AssignExp.hxx
14 // but will be inlined in runvisitor.hxx
15 // using #include with RunVisitorT class declaration.
16 //
17 // If you need additionnal headers, please add it in runvisitor.hxx
18
19 void visitprivate(const AssignExp  &e)
20 {
21     /*Create local exec visitor*/
22     try
23     {
24         /*get king of left hand*/
25         const SimpleVar *pVar = dynamic_cast<const SimpleVar*>(&e.left_exp_get());
26         if (pVar)
27         {
28             // x = ?
29             /*getting what to assign*/
30             InternalType *pIT = e.right_val_get();
31             if (pIT == NULL)
32             {
33                 expected_size_set(1);
34                 e.right_exp_get().accept(*this);
35
36                 if (result_getSize() != 1)
37                 {
38                     std::wostringstream os;
39                     os << L"Can not assign multiple value in a single variable" << std::endl;;
40                     //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
41                     throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
42                 }
43
44                 pIT = result_get();
45                 //reset result
46                 result_set(NULL);
47             }
48
49             if (pIT->isImplicitList())
50             {
51                 if (pIT->getAs<ImplicitList>()->isComputable())
52                 {
53                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
54                     delete pIT;
55                     pIT = pTemp;
56                 }
57             }
58
59             const ReturnExp *pReturn = dynamic_cast<const ReturnExp*>(&e.right_exp_get());
60             if (pReturn)
61             {
62                 //ReturnExp so, put the value in the previous scope
63                 symbol::Context::getInstance()->putInPreviousScope(pVar->name_get(), *pIT);
64                 ((AssignExp*)&e)->break_set();
65             }
66             else
67             {
68                 symbol::Context::getInstance()->put(pVar->name_get(), *pIT);
69             }
70
71             if (e.is_verbose() && ConfigVariable::isPromptShow())
72             {
73                 std::wostringstream ostr;
74                 ostr << pVar->name_get().name_get() << L"  = " << std::endl << std::endl;
75                 scilabWriteW(ostr.str().c_str());
76                 VariableToString(pIT);
77             }
78             return;
79         }
80
81         const CellCallExp *pCell = dynamic_cast<const CellCallExp*>(&e.left_exp_get());
82         if (pCell)
83         {
84             InternalType *pIT;
85             bool bRet           = true;
86             bool bNew           = false;
87
88             //retrieve variable
89             pVar = dynamic_cast<const SimpleVar*>(&pCell->name_get());
90             if (pVar == NULL)
91             {
92                 //manage a.b{1} = x
93                 pCell->name_get().accept(*this);
94
95                 if (result_get() != NULL && result_get()->isCell())
96                 {
97                     pIT = result_get();
98                 }
99                 else
100                 {
101                     //never append ?
102                     std::wostringstream os;
103                     os << _W("Unable to extract left part expression.\n");
104                     //os << ((Location)e.left_exp_get().location_get()).location_getString() << std::endl;
105                     throw ScilabError(os.str(), 999, e.left_exp_get().location_get());
106                 }
107                 //reset result
108                 result_set(NULL);
109             }
110             else
111             {
112                 pIT = symbol::Context::getInstance()->get(pVar->name_get());
113             }
114
115             /*getting what to assign*/
116             InternalType* pITR = e.right_val_get();
117             if (pITR == NULL)
118             {
119                 e.right_exp_get().accept(*this);
120                 pITR = result_get();
121                 //reset result
122                 result_set(NULL);
123             }
124
125             if (pITR == NULL)
126             {
127                 // if the right hand is NULL.
128                 std::wostringstream os;
129                 os << _W("Unable to extract right part expression.\n");
130                 throw ScilabError(os.str(), 999, e.left_exp_get().location_get());
131             }
132
133             if (pIT == NULL)
134             {
135                 //Var doesn't exist, create it with good dimensions
136                 bNew = true;
137             }
138             else
139             {
140                 if (pIT->isRef(1) == true)
141                 {
142                     pIT = pIT->clone();
143                     bNew = true;
144                 }
145             }
146
147             InternalType *pOut  = NULL;
148             typed_list *pArgs = GetArgumentList(pCell->args_get());
149
150             //fisrt extract implicit list
151             if (pITR->isImplicitList())
152             {
153                 InternalType *pIL = ((InternalType*)result_get())->getAs<ImplicitList>()->extractFullMatrix();
154                 if (result_get()->isDeletable())
155                 {
156                     delete result_get();
157                 }
158                 result_set(pIL);
159             }
160             else if (result_get()->isContainer() && result_get()->isDeletable() == false)
161             {
162                 InternalType* pIL = result_get()->clone();
163                 result_set(pIL);
164             }
165
166
167             if (pIT == NULL)
168             {
169                 //call static insert function
170                 pOut = Cell::insertNewCell(pArgs, result_get());
171             }
172             else
173             {
174                 //call type insert function
175                 pOut = pIT->getAs<Cell>()->insertCell(pArgs, result_get());
176
177                 if (pOut && pOut != pIT)
178                 {
179                     //variable change
180                     pIT->DecreaseRef();
181                     if (pIT->isDeletable())
182                     {
183                         delete pIT;
184                     }
185                     bNew = true;
186                 }
187             }
188
189
190             if (pOut != NULL)
191             {
192                 if (bNew)
193                 {
194                     symbol::Context::getInstance()->put(pVar->name_get(), *pOut);
195                 }
196
197                 if (e.is_verbose() && ConfigVariable::isPromptShow())
198                 {
199                     std::wostringstream ostr;
200                     if (pVar)
201                     {
202                         ostr << pVar->name_get().name_get() << L"  = " << std::endl;
203                     }
204                     else
205                     {
206                         ostr << L"???" << L"  = " << std::endl;
207                     }
208                     ostr << std::endl;
209                     VariableToString(pOut);
210                 }
211             }
212             else
213             {
214                 //manage error
215                 std::wostringstream os;
216                 os << _W("Invalid Index.\n");
217                 //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
218                 throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
219             }
220             //            delete piMaxDim;
221             //            delete[] piDimSize;
222             for (int iArg = 0 ; iArg < pArgs->size() ; iArg++)
223             {
224                 if ((*pArgs)[iArg]->isDeletable())
225                 {
226                     delete (*pArgs)[iArg];
227                 }
228             }
229             delete pArgs;
230             return;
231         }
232
233         const CallExp *pCall = dynamic_cast<const CallExp*>(&e.left_exp_get());
234         if (pCall)
235         {
236             //x(?) = ?
237             InternalType *pIT;
238             bool bNew   = false;
239
240             pVar = dynamic_cast<const SimpleVar*>(&pCall->name_get());
241             if (pVar == NULL)
242             {
243                 //manage a.b(1) = x
244                 pCall->name_get().accept(*this);
245
246                 if (result_get() != NULL)
247                 {
248                     pIT = result_get();
249                 }
250                 else
251                 {
252                     //never append ?
253                     std::wostringstream os;
254                     os << _W("Unable to extract left part expression.\n");
255                     //os << ((Location)e.left_exp_get().location_get()).location_getString() << std::endl;
256                     throw ScilabError(os.str(), 999, e.left_exp_get().location_get());
257                 }
258
259                 result_set(NULL);
260             }
261             else
262             {
263                 pIT = symbol::Context::getInstance()->getCurrentLevel(pVar->name_get());
264             }
265
266             /*getting what to assign*/
267             InternalType* pITR = e.right_val_get();
268             if (pITR == NULL)
269             {
270                 e.right_exp_get().accept(*this);
271                 pITR = result_get();
272                 //reset result
273                 result_set(NULL);
274             }
275
276             if (pITR == NULL)
277             {
278                 // if the right hand is NULL.
279                 std::wostringstream os;
280                 os << _W("Unable to extract right part expression.\n");
281                 throw ScilabError(os.str(), 999, e.left_exp_get().location_get());
282             }
283
284             if (pIT == NULL)
285             {
286                 //Var doesn't exist, create it with good dimensions
287                 bNew = true;
288             }
289             else
290             {
291                 if (pIT->isRef(1) == true)
292                 {
293                     InternalType* pITTemp = pIT->clone();
294                     pIT = pITTemp;
295                     bNew = true;
296                 }
297             }
298
299             typed_list *pArgs = GetArgumentList(pCall->args_get());
300             InternalType *pOut  = NULL;
301
302             //fisrt extract implicit list
303             if (pITR->isColon())
304             {
305                 //double* pdbl = NULL;
306                 //pITR = new Double(-1, -1, &pdbl);
307                 //pdbl[0] = 1;
308                 pITR = Double::Identity(-1, -1);
309             }
310             else if (pITR->isImplicitList())
311             {
312                 InternalType *pIL = pITR->getAs<ImplicitList>()->extractFullMatrix();
313                 if (pIL)
314                 {
315                     pITR = pIL;
316                 }
317             }
318             else if (pITR->isContainer() && pITR->isRef())
319             {
320                 //std::cout << "assign container type during insertion" << std::endl;
321                 InternalType* pIL = pITR->clone();
322                 pITR = pIL;
323             }
324
325             if (pITR->isDouble() && pITR->getAs<Double>()->isEmpty() && pIT == NULL)
326             {
327                 // l(x) = [] when l is not defined => create l = []
328                 pOut = Double::Empty();
329                 bNew = true;
330             }
331             else if (pITR->isDouble() && pITR->getAs<Double>()->isEmpty() && pIT->isStruct() == false && pIT->isList() == false)
332             {
333                 //insert [] so deletion except for Struct and List which can insert []
334                 if (pIT->isDouble())
335                 {
336                     pOut = pIT->getAs<Double>()->remove(pArgs);
337                 }
338                 else if (pIT->isString())
339                 {
340                     pOut = pIT->getAs<String>()->remove(pArgs);
341                 }
342                 else if (pIT->isCell())
343                 {
344                     pOut = pIT->getAs<Cell>()->remove(pArgs);
345                 }
346                 else if (pIT->isBool())
347                 {
348                     pOut = pIT->getAs<Bool>()->remove(pArgs);
349                 }
350                 else if (pIT->isPoly())
351                 {
352                     pOut = pIT->getAs<Polynom>()->remove(pArgs);
353                 }
354                 else if (pIT->isInt8())
355                 {
356                     pOut = pIT->getAs<Int8>()->remove(pArgs);
357                 }
358                 else if (pIT->isUInt8())
359                 {
360                     pOut = pIT->getAs<UInt8>()->remove(pArgs);
361                 }
362                 else if (pIT->isInt16())
363                 {
364                     pOut = pIT->getAs<Int16>()->remove(pArgs);
365                 }
366                 else if (pIT->isUInt16())
367                 {
368                     pOut = pIT->getAs<UInt16>()->remove(pArgs);
369                 }
370                 else if (pIT->isInt32())
371                 {
372                     pOut = pIT->getAs<Int32>()->remove(pArgs);
373                 }
374                 else if (pIT->isUInt32())
375                 {
376                     pOut = pIT->getAs<UInt32>()->remove(pArgs);
377                 }
378                 else if (pIT->isInt64())
379                 {
380                     pOut = pIT->getAs<Int64>()->remove(pArgs);
381                 }
382                 else if (pIT->isUInt64())
383                 {
384                     pOut = pIT->getAs<UInt64>()->remove(pArgs);
385                 }
386                 else if (pIT->isStruct())
387                 {
388                     // a("b") = [] is not a deletion !!
389                     Struct* pStr = pIT->getAs<Struct>();
390
391                     pOut = pIT->getAs<Struct>()->insert(pArgs, pITR);
392                 }
393
394                 if (pOut && pOut != pIT)
395                 {
396                     bNew = true;
397                 }
398             }
399             else if (pIT == NULL || (pIT->isDouble() && pIT->getAs<Double>()->getSize() == 0))
400             {
401                 //insert in a new variable or []
402                 //call static insert function
403                 //special case for insertion in []
404                 if (pIT != NULL && pIT->isDouble() && pIT->getAs<Double>()->getSize() == 0)
405                 {
406                     bNew = true;
407                 }
408
409                 //if pIT == NULL and pArg is single string, it's a struct creation
410                 if ((*pArgs)[0]->isString())
411                 {
412                     String *pS = (*pArgs)[0]->getAs<types::String>();
413                     Struct* pStr = new Struct(1, 1);
414
415                     if (pArgs->size() != 1 || pS->isScalar() == false)
416                     {
417                         //manage error
418                         std::wostringstream os;
419                         os << _W("Invalid Index.\n");
420                         //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
421                         throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
422                     }
423
424                     pStr->addField(pS->get(0));
425                     pStr->get(0)->set(pS->get(0), pITR);
426                     pOut = pStr;
427                 }
428                 else
429                 {
430                     switch (pITR->getType())
431                     {
432                         case InternalType::RealDouble :
433                             pOut = Double::insertNew(pArgs, pITR);
434                             break;
435                         case InternalType::RealString :
436                             pOut = String::insertNew(pArgs, pITR);
437                             break;
438                         case InternalType::RealCell :
439                             pOut = Cell::insertNew(pArgs, pITR);
440                             break;
441                         case InternalType::RealBool :
442                             pOut = Bool::insertNew(pArgs, pITR);
443                             break;
444                         case InternalType::RealPoly :
445                             pOut = Polynom::insertNew(pArgs, pITR);
446                             break;
447                         case InternalType::RealInt8 :
448                             pOut = Int8::insertNew(pArgs, pITR);
449                             break;
450                         case InternalType::RealUInt8 :
451                             pOut = UInt8::insertNew(pArgs, pITR);
452                             break;
453                         case InternalType::RealInt16 :
454                             pOut = Int16::insertNew(pArgs, pITR);
455                             break;
456                         case InternalType::RealUInt16 :
457                             pOut = UInt16::insertNew(pArgs, pITR);
458                             break;
459                         case InternalType::RealInt32 :
460                             pOut = Int32::insertNew(pArgs, pITR);
461                             break;
462                         case InternalType::RealUInt32 :
463                             pOut = UInt32::insertNew(pArgs, pITR);
464                             break;
465                         case InternalType::RealInt64 :
466                             pOut = Int64::insertNew(pArgs, pITR);
467                             break;
468                         case InternalType::RealUInt64 :
469                             pOut = UInt64::insertNew(pArgs, pITR);
470                             break;
471                         case InternalType::RealSparse :
472                             pOut = Sparse::insertNew(pArgs, pITR);
473                             break;
474                         case InternalType::RealSparseBool :
475                             pOut = SparseBool::insertNew(pArgs, pITR);
476                             break;
477                         default :
478                         {
479                             //manage error
480                             std::wostringstream os;
481                             os << _W("Operation not yet managed.\n");
482                             //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
483                             throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
484                             break;
485                         }
486                     }
487                 }
488             }
489             else
490             {
491                 //call type insert function
492                 InternalType* pRet = NULL;
493                 InternalType* pInsert = pITR;
494                 //check types compatibilties
495
496                 if (pIT->isDouble() && pInsert->isDouble())
497                 {
498                     pRet = pIT->getAs<Double>()->insert(pArgs, pInsert);
499                 }
500                 else if (pIT->isDouble() && pInsert->isSparse())
501                 {
502                     Sparse* pSp = pInsert->getAs<Sparse>();
503                     Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
504                     pSp->fill(*pD);
505                     pRet = pIT->getAs<Double>()->insert(pArgs, pD);
506                     free(pD);
507                 }
508                 else if (pIT->isString() && pInsert->isString())
509                 {
510                     pRet = pIT->getAs<String>()->insert(pArgs, pInsert);
511                 }
512                 else if (pIT->isCell() && pInsert->isCell())
513                 {
514                     pRet = pIT->getAs<Cell>()->insert(pArgs, pInsert);
515                 }
516                 else if (pIT->isBool() && pInsert->isBool())
517                 {
518                     pRet = pIT->getAs<Bool>()->insert(pArgs, pInsert);
519                 }
520                 else if (pIT->isSparse() && pInsert->isSparse())
521                 {
522                     pRet = pIT->getAs<Sparse>()->insert(pArgs, pInsert->getAs<Sparse>());
523                 }
524                 else if (pIT->isSparse() && pInsert->isDouble())
525                 {
526                     pRet = pIT->getAs<Sparse>()->insert(pArgs, pInsert);
527                 }
528                 else if (pIT->isSparseBool() && pInsert->isSparseBool())
529                 {
530                     pRet = pIT->getAs<SparseBool>()->insert(pArgs, pInsert->getAs<SparseBool>());
531                 }
532                 else if (pIT->isSparseBool() && pInsert->isBool())
533                 {
534                     pRet = pIT->getAs<SparseBool>()->insert(pArgs, pInsert);
535                 }
536                 else if (pIT->isPoly() && pInsert->isDouble())
537                 {
538                     Polynom* pDest = pIT->getAs<Polynom>();
539                     Double* pIns = pInsert->getAs<Double>();
540                     Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray());
541                     pP->setComplex(pIns->isComplex());
542
543                     for (int idx = 0 ; idx < pP->getSize() ; idx++)
544                     {
545                         double* pR = NULL;
546                         double* pI = NULL;
547                         if (pP->isComplex())
548                         {
549                             SinglePoly* pS = new SinglePoly(&pR, &pI, 1);
550                             double dblR = pIns->get(idx);
551                             double dblI = pIns->getImg(idx);
552                             pS->setCoef(&dblR, &dblI);
553                             pP->set(idx, pS);
554                             delete pS;
555                         }
556                         else
557                         {
558                             SinglePoly* pS = new SinglePoly(&pR, 1);
559                             double dblR = pIns->get(idx);
560                             pS->setCoef(&dblR, NULL);
561                             pP->set(idx, pS);
562                             delete pS;
563                         }
564                     }
565                     pRet = pIT->getAs<Polynom>()->insert(pArgs, pP);
566                     delete pP;
567                 }
568                 else if (pIT->isPoly() && pInsert->isPoly())
569                 {
570                     pRet = pIT->getAs<Polynom>()->insert(pArgs, pInsert);
571                 }
572                 else if (pIT->isInt8() && pInsert->isInt8())
573                 {
574                     pRet = pIT->getAs<Int8>()->insert(pArgs, pInsert);
575                 }
576                 else if (pIT->isUInt8() && pInsert->isUInt8())
577                 {
578                     pRet = pIT->getAs<UInt8>()->insert(pArgs, pInsert);
579                 }
580                 else if (pIT->isInt16() && pInsert->isInt16())
581                 {
582                     pRet = pIT->getAs<Int16>()->insert(pArgs, pInsert);
583                 }
584                 else if (pIT->isUInt16() && pInsert->isUInt16())
585                 {
586                     pRet = pIT->getAs<UInt16>()->insert(pArgs, pInsert);
587                 }
588                 else if (pIT->isInt32() && pInsert->isInt32())
589                 {
590                     pRet = pIT->getAs<Int32>()->insert(pArgs, pInsert);
591                 }
592                 else if (pIT->isUInt32() && pInsert->isUInt32())
593                 {
594                     pRet = pIT->getAs<UInt32>()->insert(pArgs, pInsert);
595                 }
596                 else if (pIT->isInt64() && pInsert->isInt64())
597                 {
598                     pRet = pIT->getAs<Int64>()->insert(pArgs, pInsert);
599                 }
600                 else if (pIT->isUInt64() && pInsert->isUInt64())
601                 {
602                     pRet = pIT->getAs<UInt64>()->insert(pArgs, pInsert);
603                 }
604                 else if (pIT->isStruct())
605                 {
606                     Struct* pStr = pIT->getAs<Struct>();
607                     if (pArgs->size() == 1 && (*pArgs)[0]->isString())
608                     {
609                         //s("x") = y
610                         String *pS = (*pArgs)[0]->getAs<types::String>();
611                         if (pS->isScalar() == false)
612                         {
613                             //manage error
614                             std::wostringstream os;
615                             os << _W("Invalid Index.\n");
616                             //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
617                             throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
618                         }
619
620                         pStr->addField(pS->get(0));
621                         pStr->get(0)->set(pS->get(0), pInsert);
622                         pRet = pStr;
623                     }
624                     else
625                     {
626                         pRet = pStr->insert(pArgs, pInsert);
627                     }
628                 }
629                 else if (pIT->isTList() || pIT->isMList())
630                 {
631                     TList* pTL = pIT->getAs<TList>();
632                     if (pArgs->size() == 1 && (*pArgs)[0]->isString())
633                     {
634                         //s("x") = y
635                         String *pS = (*pArgs)[0]->getAs<types::String>();
636                         if (pS->isScalar() == false)
637                         {
638                             //manage error
639                             std::wostringstream os;
640                             os << _W("Invalid Index.\n");
641                             //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
642                             throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
643                         }
644
645                         pTL->set(pS->get(0), pInsert);
646                         pRet = pTL;
647                     }
648                     else
649                     {
650                         pRet = pTL->insert(pArgs, pInsert);
651                     }
652                 }
653                 else if (pIT->isList())
654                 {
655                     pRet = pIT->getAs<List>()->insert(pArgs, pInsert);
656                 }
657                 else if (pIT->isHandle())
658                 {
659                     if (pArgs->size() == 1 && (*pArgs)[0]->isString())
660                     {
661                         //s(["x"])
662                         types::GraphicHandle* pH = pIT->getAs<types::GraphicHandle>();
663                         types::String *pS = (*pArgs)[0]->getAs<types::String>();
664                         typed_list in;
665                         typed_list out;
666                         optional_list opt;
667
668                         in.push_back(pH);
669                         in.push_back(pS);
670                         in.push_back(pInsert);
671
672                         Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
673                         Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, this);
674                         if (ret == Callable::OK)
675                         {
676                             pRet = pIT;
677                         }
678                     }
679                     else
680                     {
681                         pRet = pIT->getAs<types::GraphicHandle>()->extract(pArgs);
682                     }
683                 }
684                 else
685                 {
686                     //overloading
687                     types::typed_list in;
688                     types::typed_list out;
689
690                     //overload insertion
691                     //%x_i_x(i1, i2, ..., in, source, dest)
692                     //i1, ..., in : indexes
693                     //dest : variable where to insert data
694                     //source : data to insert
695
696                     for (int i = 0 ; i < pArgs->size() ; i++)
697                     {
698                         (*pArgs)[i]->IncreaseRef();
699                         in.push_back((*pArgs)[i]);
700                     }
701
702                     pInsert->IncreaseRef();
703                     in.push_back(pInsert);
704
705                     pIT->IncreaseRef();
706                     in.push_back(pIT);
707
708                     //build function name
709                     //a_i_b
710                     //a : type to insert
711                     //b : type that receive data
712                     std::wstring function_name;
713                     function_name = L"%" + pInsert->getShortTypeStr() + L"_i_" + pIT->getShortTypeStr();
714                     Overload::call(function_name, in, 1, out, this);
715
716                     pIT->DecreaseRef();
717                     pInsert->DecreaseRef();
718                     for (int i = 0 ; i < pArgs->size() ; i++)
719                     {
720                         (*pArgs)[i]->DecreaseRef();
721                     }
722
723                     if (out.size() != 0)
724                     {
725                         pRet = out[0];
726                     }
727                     else
728                     {
729                         pRet = NULL;
730                     }
731                 }
732
733                 if (pRet && pRet != pIT)
734                 {
735                     bNew = true;
736                 }
737
738                 pOut = pRet;
739             }
740
741             if (pOut != NULL)
742             {
743                 if (bNew)
744                 {
745                     if (pVar == NULL && pIT->isHandle() == false)
746                     {
747                         //is not a(x) = y but something like a.b(x) = y
748                         //so we have to retrieve struct and children to assign new value
749                         InternalType *pHead     = NULL;
750                         InternalType* pMain     = NULL;
751                         InternalType* pCurrent  = NULL;
752                         bool bOK = getStructFromExp(&pCall->name_get(), &pMain, &pCurrent, NULL, pOut);
753                         //change pOut only to toString call
754                         pOut = pMain;
755                     }
756                     else
757                     {
758                         symbol::Context::getInstance()->put(pVar->name_get(), *((GenericType*)pOut));
759                     }
760                 }
761
762                 if (e.is_verbose() && ConfigVariable::isPromptShow())
763                 {
764                     std::wostringstream ostr;
765                     if (pVar)
766                     {
767                         ostr << pVar->name_get().name_get() << L"  = " << std::endl;
768                     }
769                     else
770                     {
771                         ostr << *getStructNameFromExp(&pCall->name_get()) << L"  = " << std::endl;
772                     }
773
774                     ostr << std::endl;
775                     scilabWriteW(ostr.str().c_str());
776                     VariableToString(pOut);
777                 }
778             }
779             else
780             {
781                 //manage error
782                 std::wostringstream os;
783                 os << _W("Invalid index.\n");
784                 //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
785                 throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
786             }
787             //delete piMaxDim;
788             //delete[] piDimSize;
789             for (int iArg = 0 ; iArg < pArgs->size() ; iArg++)
790             {
791                 if ((*pArgs)[iArg]->isDeletable())
792                 {
793                     delete (*pArgs)[iArg];
794                 }
795             }
796             result_clear();
797             delete pArgs;
798             return;
799         }
800
801         const AssignListExp *pList = dynamic_cast<const AssignListExp*>(&e.left_exp_get());
802         if (pList)
803         {
804             //[x,y] = ?
805             int iLhsCount = (int)pList->exps_get().size();
806
807             /*getting what to assign*/
808             T exec;
809             exec.expected_size_set(iLhsCount);
810             e.right_exp_get().accept(exec);
811
812             if (exec.result_getSize() != iLhsCount)
813             {
814                 std::wostringstream os;
815                 os << L"Incompatible assignation: trying to assign " << exec.result_getSize();
816                 os << " values in " << iLhsCount << " variables." << std::endl;
817                 throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
818             }
819
820             std::list<Exp *>::const_reverse_iterator it;
821             int i = (int)iLhsCount - 1;
822             for (it = pList->exps_get().rbegin() ; it != pList->exps_get().rend() ; it++, i--)
823             {
824                 //create a new AssignExp and run it
825                 AssignExp* pAssign = new AssignExp((*it)->location_get(), *(*it), *const_cast<Exp*>(&e.right_exp_get()), exec.result_get(i));
826                 pAssign->set_verbose(e.is_verbose());
827                 pAssign->accept(*this);
828
829                 //clear result to take care of [n,n]
830                 exec.result_set(i, NULL);
831             }
832             exec.result_clear();
833             return;
834         }
835
836         const FieldExp *pField = dynamic_cast<const FieldExp*>(&e.left_exp_get());
837         if (pField)
838         {
839             //a.b = x
840             //a.b can be a struct or a tlist/mlist or a handle
841             /*getting what to assign*/
842             expected_size_set(1);
843             e.right_exp_get().accept(*this);
844             InternalType *pIT = result_get();
845             if (pIT->isImplicitList())
846             {
847                 if (pIT->getAs<ImplicitList>()->isComputable())
848                 {
849                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
850                     delete pIT;
851                     result_set(NULL);
852                     pIT = pTemp;
853                 }
854             }
855             else if (pIT->isContainer())
856             {
857                 //if assigned value is a container, copy it before assign.
858                 //std::cout << "assign container type to field" << std::endl;
859                 //pIT = pIT->clone();
860             }
861
862             //try to find struct or handle
863             {
864                 InternalType* pMain     = NULL;
865                 InternalType* pCurrent  = NULL;
866                 const Exp* pCurrentExp  = pField;
867
868                 const wstring *pstName  = getStructNameFromExp(pField);
869                 if (pstName)
870                 {
871                     InternalType* pCurrentStr = symbol::Context::getInstance()->getCurrentLevel(symbol::Symbol(*pstName));
872                     InternalType* pHigherStr = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
873                     if (pHigherStr && pHigherStr->isStruct() && pCurrentStr == NULL)
874                     {
875                         //struct come from higher scope, so we need to clone and put it in current scope
876                         InternalType *pITClone = pHigherStr->clone();
877                         symbol::Context::getInstance()->put(symbol::Symbol(*pstName), *pITClone);
878                     }
879                 }
880
881                 bool bOK = getStructFromExp(pCurrentExp, &pMain, &pCurrent, NULL, pIT);
882                 if (bOK)
883                 {
884                     //someting was done
885                 }
886                 else
887                 {
888                     //not a struct/handle but it can be a MList ou TList
889                     pField->head_get()->accept(*this);
890                     InternalType *pHead = result_get();
891
892                     if (pHead->isMList())
893                     {
894                         //TODO:
895                     }
896                     else if (pHead->isTList())
897                     {
898                         //assign result to new field
899                         const SimpleVar* pTail =  dynamic_cast<const SimpleVar*>(pField->tail_get());
900                         TList* pT = pHead->getAs<TList>();
901                         if (pT->exists(pTail->name_get().name_get()))
902                         {
903                             pT->set(pTail->name_get().name_get(), pIT);
904                         }
905                         else
906                         {
907                             std::wostringstream os;
908                             os << L"Field must be exist";
909                             throw ScilabError(os.str(), 999, pVar->location_get());
910                         }
911                     }
912                     else
913                     {
914                         std::wostringstream os;
915                         os << L"invalid operation";
916                         throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
917                     }
918                 }
919             }
920
921             //if(pHead->isStruct() || pHead == NULL)
922             //{
923             //    InternalType* pMain     = NULL;
924             //    InternalType* pCurrent  = NULL;
925             //    const Exp* pCurrentExp  = pField;
926             //    const wstring *pstName  = getStructNameFromExp(pField);
927             //    if(pstName)
928             //    {
929             //        InternalType* pCurrentStr = symbol::Context::getInstance()->getCurrentLevel(symbol::Symbol(*pstName));
930             //        InternalType* pHigherStr = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
931             //        if(pHigherStr && pCurrentStr == NULL)
932             //        {//struct come from higher scope, so we need to clone and put it in current scope
933             //            InternalType *pITClone = pHigherStr->clone();
934             //            symbol::Context::getInstance()->put(symbol::Symbol(*pstName), *pITClone);
935             //        }
936             //    }
937
938             //    if(pHead != NULL)
939             //    {
940             //        pMain = pHead->getAs<Struct>();
941             //        pCurrentExp = pField->tail_get();
942             //    }
943
944             //    bool bOK = getStructFromExp(pCurrentExp, &pMain, &pCurrent, NULL, pIT);
945             //    if (pMain != NULL)
946             //    {
947             //        pHead = pMain;
948             //    }
949
950             //    //if a is already assign, make a copy and replace it
951             //    if (pHead->isRef(1) == true)
952             //    {
953             //        pHead = pHead->clone();
954             //        pstName = getStructNameFromExp(pField);
955             //        symbol::Context::getInstance()->put(symbol::Symbol(*pstName), *pHead->clone());
956             //    }
957             //}
958             //else if(pHead->isMList())
959             //{
960             //    //TODO:
961             //}
962             //else if(pHead->isTList())
963             //{
964             //    //assign result to new field
965             //    const SimpleVar* pTail =  dynamic_cast<const SimpleVar*>(pField->tail_get());
966             //    TList* pT = pHead->getAs<TList>();
967             //    if (pT->exists(pTail->name_get().name_get()))
968             //    {
969             //        pT->set(pTail->name_get().name_get(), pIT);
970             //    }
971             //    else
972             //    {
973             //        std::wostringstream os;
974             //        os << L"Field must be exist";
975             //        throw ScilabError(os.str(), 999, pVar->location_get());
976             //    }
977             //}
978             //else if(pHead->isHandle())
979             //{
980             //    //parse head exp to create a list of "index" to call %x_i_h macro
981             //    //List* pList = getPropertyTree((Exp*)pField->tail_get(), new List());
982             //    //typed_list arg;
983             //    //arg.push_back(new Double(1));
984             //    //ListDelete* pDel = new ListDelete();
985             //    //pList->insert(&arg, pDel);
986             //    //delete pDel;
987             //    //delete arg[0];
988
989             //    //call overload %x_i_h
990             //    String* pS = new String(((SimpleVar*)pField->tail_get())->name_get().name_get().c_str());
991             //    std::wstring str = L"%" + pIT->getShortTypeStr() + L"_i_h";
992
993             //    typed_list in;
994             //    typed_list out;
995             //    optional_list opt;
996
997             //    in.push_back(pS);
998             //    in.push_back(pIT);
999             //    in.push_back(pHead);
1000             //    pS->IncreaseRef();
1001             //    pIT->IncreaseRef();
1002             //    pHead->IncreaseRef();
1003
1004             //    Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(str));
1005             //    Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, this);
1006             //    //delete pS;
1007
1008             //    pS->DecreaseRef();
1009             //    pIT->DecreaseRef();
1010             //    pHead->DecreaseRef();
1011             //    if(ret != Callable::OK)
1012             //    {
1013             //        std::wostringstream os;
1014             //        os << L"unable to update handle";
1015             //        throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
1016             //    }
1017             //}
1018             //else
1019             //{
1020             //    std::wostringstream os;
1021             //    os << L"invalid operation";
1022             //    throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
1023             //}
1024
1025             if (e.is_verbose() && ConfigVariable::isPromptShow())
1026             {
1027                 const wstring *pstName = getStructNameFromExp(pField);
1028
1029                 types::InternalType* pPrint = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
1030                 std::wostringstream ostr;
1031                 ostr << *pstName << L"  = " << std::endl << std::endl;
1032                 scilabWriteW(ostr.str().c_str());
1033                 VariableToString(pPrint);
1034             }
1035
1036             result_clear();
1037             return;
1038         }
1039
1040         std::wostringstream os;
1041         os << L"unknow script form";
1042         //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
1043         throw ScilabError(os.str(), 999, e.right_exp_get().location_get());
1044     }
1045     catch (ScilabError error)
1046     {
1047         throw error;
1048     }
1049 }