81204fa2ba742ad3e681ecfc40b5c120adab2a5b
[scilab.git] / scilab / modules / ast / src / cpp / ast / run_AssignExp.cpp
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 //file included in runvisitor.cpp
14
15 template<class T>
16 void RunVisitorT<T>::visitprivate(const AssignExp  &e)
17 {
18     /*Create local exec visitor*/
19     try
20     {
21         SimpleVar * pVar = NULL;
22         if (e.getLeftExp().isSimpleVar())
23         {
24             pVar = static_cast<SimpleVar*>(&e.getLeftExp());
25         }
26
27         /*get king of left hand*/
28         if (pVar)
29         {
30             // x = ?
31             /*getting what to assign*/
32             InternalType *pIT = e.getRightVal();
33             if (pIT == NULL)
34             {
35                 setExpectedSize(1);
36                 e.getRightExp().accept(*this);
37
38                 if (getResultSize() != 1)
39                 {
40                     std::wostringstream os;
41                     os << _W("Can not assign multiple value in a single variable") << std::endl;
42                     //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
43                     throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
44                 }
45
46                 pIT = getResult();
47                 //reset result
48                 setResult(NULL);
49             }
50
51             if (pIT->isImplicitList())
52             {
53                 if (pIT->getAs<ImplicitList>()->isComputable())
54                 {
55                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
56                     delete pIT;
57                     pIT = pTemp;
58                 }
59             }
60
61             if (pIT->isAssignable() == false)
62             {
63                 if (pIT->isListDelete())
64                 {
65                     //used to delete a variable in current scope
66                     symbol::Context::getInstance()->remove(pVar->getSymbol());
67                 }
68
69                 setResult(NULL);
70                 return;
71             }
72
73             if (e.getRightExp().isReturnExp())
74             {
75                 //ReturnExp so, put the value in the previous scope
76                 symbol::Context::getInstance()->putInPreviousScope(pVar->getStack(), pIT);
77                 ((AssignExp*)&e)->setReturn();
78             }
79             else
80             {
81                 symbol::Context::getInstance()->put(pVar->getStack(), pIT);
82             }
83
84             if (e.isVerbose() && ConfigVariable::isPromptShow())
85             {
86                 std::wstring wstrName = pVar->getSymbol().getName();
87                 std::wostringstream ostr;
88                 ostr << wstrName << L"  = " << std::endl << std::endl;
89                 scilabWriteW(ostr.str().c_str());
90                 std::wostringstream ostrName;
91                 ostrName << SPACES_LIST << wstrName;
92                 VariableToString(pIT, ostrName.str().c_str());
93             }
94             return;
95         }
96
97         CellCallExp *pCell = dynamic_cast<CellCallExp*>(&e.getLeftExp());
98         if (pCell)
99         {
100             InternalType *pOut  = NULL;
101
102             /*getting what to assign*/
103             InternalType* pITR = e.getRightVal();
104             if (pITR == NULL)
105             {
106                 e.getRightExp().accept(*this);
107                 pITR = getResult();
108                 //reset result
109                 setResult(NULL);
110             }
111
112             if (pITR == NULL)
113             {
114                 // if the right hand is NULL.
115                 std::wostringstream os;
116                 os << _W("Unable to extract right part expression.\n");
117                 throw ast::ScilabError(os.str(), 999, e.getLeftExp().getLocation());
118             }
119
120             std::list<ExpHistory*> fields;
121             if (getFieldsFromExp(pCell, fields) == false)
122             {
123                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
124                 {
125                     delete *i;
126                 }
127                 std::wostringstream os;
128                 os << _W("Get fields from expression failed.");
129                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
130             }
131
132             try
133             {
134                 pOut = evaluateFields(pCell, fields, pITR);
135             }
136             catch (ast::ScilabError error)
137             {
138                 // catch error when call overload
139                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
140                 {
141                     (*i)->setDeleteCurrent(true);
142                     delete *i;
143                 }
144
145                 pITR->killMe();
146                 throw error;
147             }
148
149             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
150             {
151                 delete *i;
152             }
153
154             pITR->killMe();
155
156             if (pOut == NULL)
157             {
158                 std::wostringstream os;
159                 os << _W("Fields evaluation failed.");
160                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
161             }
162
163             if (pOut != NULL)
164             {
165                 if (e.isVerbose() && ConfigVariable::isPromptShow())
166                 {
167                     std::wostringstream ostr;
168                     if (pCell)
169                     {
170                         const wstring *pstName = getStructNameFromExp(pCell);
171                         ostr << SPACES_LIST << pstName;
172                     }
173                     else
174                     {
175                         ostr << SPACES_LIST << L"???";
176                     }
177
178                     VariableToString(pOut, ostr.str().c_str());
179                 }
180             }
181             else
182             {
183                 //manage error
184                 std::wostringstream os;
185                 os << _W("Invalid Index.\n");
186                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
187             }
188
189             return;
190         }
191
192         CallExp *pCall = dynamic_cast<CallExp*>(&e.getLeftExp());
193         if (pCall)
194         {
195             //x(?) = ?
196             InternalType *pOut = NULL;
197
198             /*getting what to assign*/
199             InternalType* pITR = e.getRightVal();
200             if (pITR == NULL)
201             {
202                 e.getRightExp().accept(*this);
203                 pITR = getResult();
204                 //reset result
205                 setResult(NULL);
206             }
207
208             if (pITR == NULL)
209             {
210                 // if the right hand is NULL.
211                 std::wostringstream os;
212                 os << _W("Unable to extract right part expression.\n");
213                 throw ast::ScilabError(os.str(), 999, e.getLeftExp().getLocation());
214             }
215
216             std::list<ExpHistory*> fields;
217             if (getFieldsFromExp(pCall, fields) == false)
218             {
219                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
220                 {
221                     delete *i;
222                 }
223                 std::wostringstream os;
224                 os << _W("Get fields from expression failed.");
225                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
226             }
227
228             // prevent delete after extractFullMatrix
229             // called in evaluateFields when pITR is an ImplicitList
230             pITR->IncreaseRef();
231
232             try
233             {
234                 pOut = evaluateFields(pCall, fields, pITR);
235             }
236             catch (ast::ScilabError error)
237             {
238                 // catch error when call overload
239                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
240                 {
241                     delete *i;
242                 }
243
244                 pITR->DecreaseRef();
245                 pITR->killMe();
246
247                 throw error;
248             }
249
250             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
251             {
252                 delete *i;
253             }
254
255             pITR->DecreaseRef();
256             pITR->killMe();
257
258             if (pOut == NULL)
259             {
260                 std::wostringstream os;
261                 os << _W("Fields evaluation failed.");
262                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
263             }
264
265             if (e.isVerbose() && ConfigVariable::isPromptShow())
266             {
267                 std::wostringstream ostr;
268                 ostr << *getStructNameFromExp(&pCall->getName()) << L"  = " << std::endl;
269                 ostr << std::endl;
270                 scilabWriteW(ostr.str().c_str());
271
272                 std::wostringstream ostrName;
273                 ostrName << SPACES_LIST << *getStructNameFromExp(&pCall->getName());
274                 VariableToString(pOut, ostrName.str().c_str());
275             }
276
277             clearResult();
278             return;
279         }
280
281         if (e.getLeftExp().isAssignListExp())
282         {
283             AssignListExp *pList = e.getLeftExp().getAs<AssignListExp>();
284             //[x,y] = ?
285             int iLhsCount = (int)pList->getExps().size();
286
287             /*getting what to assign*/
288             T exec;
289             exec.setExpectedSize(iLhsCount);
290             e.getRightExp().accept(exec);
291
292             if (exec.getResultSize() != iLhsCount)
293             {
294                 std::wostringstream os;
295                 os << _W("Incompatible assignation: trying to assign ") << exec.getResultSize();
296                 os << _W(" values in ") << iLhsCount << _W(" variables.") << std::endl;
297                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
298             }
299
300             exps_t::const_reverse_iterator it;
301             int i = (int)iLhsCount - 1;
302             exps_t exps = pList->getExps();
303             for (it = exps.rbegin() ; it != exps.rend() ; it++, i--)
304             {
305                 //create a new AssignExp and run it
306                 types::InternalType* pIT = exec.getResult(i);
307                 AssignExp pAssign((*it)->getLocation(), *(*it), *const_cast<Exp*>(&e.getRightExp()), pIT);
308                 pAssign.setLrOwner(false);
309                 pAssign.setVerbose(e.isVerbose());
310                 pAssign.accept(*this);
311                 //clear result to take care of [n,n]
312                 exec.setResult(i, NULL);
313             }
314             exec.clearResult();
315             return;
316         }
317
318         FieldExp *pField = dynamic_cast<FieldExp*>(&e.getLeftExp());
319         if (pField)
320         {
321             //a.b = x
322             //a.b can be a struct or a tlist/mlist or a handle
323             /*getting what to assign*/
324             setExpectedSize(1);
325             e.getRightExp().accept(*this);
326             InternalType *pIT = getResult();
327             setResult(NULL);
328             if (pIT->isImplicitList())
329             {
330                 if (pIT->getAs<ImplicitList>()->isComputable())
331                 {
332                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
333                     delete pIT;
334                     setResult(NULL);
335                     pIT = pTemp;
336                 }
337             }
338
339             std::list<ExpHistory*> fields;
340             if (getFieldsFromExp(pField, fields) == false)
341             {
342                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
343                 {
344                     delete *i;
345                 }
346                 std::wostringstream os;
347                 os << _W("Get fields from expression failed.");
348                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
349             }
350
351             if (evaluateFields(pField, fields, pIT) == NULL)
352             {
353                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
354                 {
355                     delete *i;
356                 }
357                 std::wostringstream os;
358                 os << _W("Fields evaluation failed.");
359                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
360             }
361
362             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
363             {
364                 delete *i;
365             }
366
367             if (e.isVerbose() && ConfigVariable::isPromptShow())
368             {
369                 const wstring *pstName = getStructNameFromExp(pField);
370
371                 types::InternalType* pPrint = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
372                 std::wostringstream ostr;
373                 ostr << *pstName << L"  = " << std::endl << std::endl;
374                 scilabWriteW(ostr.str().c_str());
375
376                 std::wostringstream ostrName;
377                 ostrName << SPACES_LIST << *pstName;
378                 VariableToString(pPrint, ostrName.str().c_str());
379             }
380
381             clearResult();
382             return;
383         }
384
385         std::wostringstream os;
386         os << _W("unknow script form");
387         //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
388         throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
389     }
390     catch (ast::ScilabError error)
391     {
392         throw error;
393     }
394 }