fcbb09f8b21b4cf788f26b07b51e912d6ccc844a
[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             pOut = evaluateFields(pCell, fields, pITR);
133             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
134             {
135                 delete *i;
136             }
137
138             if (pOut == NULL)
139             {
140                 std::wostringstream os;
141                 os << _W("Fields evaluation failed.");
142                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
143             }
144
145             if (pOut != NULL)
146             {
147                 if (e.isVerbose() && ConfigVariable::isPromptShow())
148                 {
149                     std::wostringstream ostr;
150                     if (pVar)
151                     {
152                         ostr << SPACES_LIST << pVar->getSymbol().getName();
153                     }
154                     else
155                     {
156                         ostr << SPACES_LIST << L"???";
157                     }
158
159                     VariableToString(pOut, ostr.str().c_str());
160                 }
161             }
162             else
163             {
164                 //manage error
165                 std::wostringstream os;
166                 os << _W("Invalid Index.\n");
167                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
168             }
169
170             return;
171         }
172
173         CallExp *pCall = dynamic_cast<CallExp*>(&e.getLeftExp());
174         if (pCall)
175         {
176             //x(?) = ?
177             InternalType *pOut  = NULL;
178
179             /*getting what to assign*/
180             InternalType* pITR = e.getRightVal();
181             if (pITR == NULL)
182             {
183                 e.getRightExp().accept(*this);
184                 pITR = getResult();
185                 //reset result
186                 setResult(NULL);
187             }
188
189             if (pITR == NULL)
190             {
191                 // if the right hand is NULL.
192                 std::wostringstream os;
193                 os << _W("Unable to extract right part expression.\n");
194                 throw ast::ScilabError(os.str(), 999, e.getLeftExp().getLocation());
195             }
196
197             std::list<ExpHistory*> fields;
198             if (getFieldsFromExp(pCall, fields) == false)
199             {
200                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
201                 {
202                     delete *i;
203                 }
204                 std::wostringstream os;
205                 os << _W("Get fields from expression failed.");
206                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
207             }
208
209             pOut = evaluateFields(pCall, fields, pITR);
210             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
211             {
212                 delete *i;
213             }
214
215             if (pOut == NULL)
216             {
217                 std::wostringstream os;
218                 os << _W("Fields evaluation failed.");
219                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
220             }
221
222             if (e.isVerbose() && ConfigVariable::isPromptShow())
223             {
224                 std::wostringstream ostr;
225                 ostr << *getStructNameFromExp(&pCall->getName()) << L"  = " << std::endl;
226                 ostr << std::endl;
227                 scilabWriteW(ostr.str().c_str());
228
229                 std::wostringstream ostrName;
230                 ostrName << SPACES_LIST << *getStructNameFromExp(&pCall->getName());
231                 VariableToString(pOut, ostrName.str().c_str());
232             }
233
234             pITR->killMe();
235
236             clearResult();
237             return;
238         }
239
240         if (e.getLeftExp().isAssignListExp())
241         {
242             AssignListExp *pList = e.getLeftExp().getAs<AssignListExp>();
243             //[x,y] = ?
244             int iLhsCount = (int)pList->getExps().size();
245
246             /*getting what to assign*/
247             T exec;
248             exec.setExpectedSize(iLhsCount);
249             e.getRightExp().accept(exec);
250
251             if (exec.getResultSize() != iLhsCount)
252             {
253                 std::wostringstream os;
254                 os << _W("Incompatible assignation: trying to assign ") << exec.getResultSize();
255                 os << _W(" values in ") << iLhsCount << _W(" variables.") << std::endl;
256                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
257             }
258
259             exps_t::const_reverse_iterator it;
260             int i = (int)iLhsCount - 1;
261             exps_t exps = pList->getExps();
262             for (it = exps.rbegin() ; it != exps.rend() ; it++, i--)
263             {
264                 //create a new AssignExp and run it
265                 types::InternalType* pIT = exec.getResult(i);
266                 AssignExp pAssign((*it)->getLocation(), *(*it), *const_cast<Exp*>(&e.getRightExp()), pIT);
267                 pAssign.setLrOwner(false);
268                 pAssign.setVerbose(e.isVerbose());
269                 pAssign.accept(*this);
270                 //clear result to take care of [n,n]
271                 exec.setResult(i, NULL);
272             }
273             exec.clearResult();
274             return;
275         }
276
277         FieldExp *pField = dynamic_cast<FieldExp*>(&e.getLeftExp());
278         if (pField)
279         {
280             //a.b = x
281             //a.b can be a struct or a tlist/mlist or a handle
282             /*getting what to assign*/
283             setExpectedSize(1);
284             e.getRightExp().accept(*this);
285             InternalType *pIT = getResult();
286             setResult(NULL);
287             if (pIT->isImplicitList())
288             {
289                 if (pIT->getAs<ImplicitList>()->isComputable())
290                 {
291                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
292                     delete pIT;
293                     setResult(NULL);
294                     pIT = pTemp;
295                 }
296             }
297
298             std::list<ExpHistory*> fields;
299             if (getFieldsFromExp(pField, fields) == false)
300             {
301                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
302                 {
303                     delete *i;
304                 }
305                 std::wostringstream os;
306                 os << _W("Get fields from expression failed.");
307                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
308             }
309
310             if (evaluateFields(pField, fields, pIT) == NULL)
311             {
312                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
313                 {
314                     delete *i;
315                 }
316                 std::wostringstream os;
317                 os << _W("Fields evaluation failed.");
318                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
319             }
320
321             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
322             {
323                 delete *i;
324             }
325
326             if (e.isVerbose() && ConfigVariable::isPromptShow())
327             {
328                 const wstring *pstName = getStructNameFromExp(pField);
329
330                 types::InternalType* pPrint = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
331                 std::wostringstream ostr;
332                 ostr << *pstName << L"  = " << std::endl << std::endl;
333                 scilabWriteW(ostr.str().c_str());
334
335                 std::wostringstream ostrName;
336                 ostrName << SPACES_LIST << *pstName;
337                 VariableToString(pPrint, ostrName.str().c_str());
338             }
339
340             clearResult();
341             return;
342         }
343
344         std::wostringstream os;
345         os << _W("unknow script form");
346         //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
347         throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
348     }
349     catch (ast::ScilabError error)
350     {
351         throw error;
352     }
353 }