delete of opt arguments corrected.
[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.left_exp_get().is_simple_var())
23         {
24             pVar = static_cast<SimpleVar*>(&e.left_exp_get());
25         }
26
27         /*get king of left hand*/
28         if (pVar)
29         {
30             // x = ?
31             /*getting what to assign*/
32             InternalType *pIT = e.right_val_get();
33             if (pIT == NULL)
34             {
35                 expected_setSize(1);
36                 e.right_exp_get().accept(*this);
37
38                 if (result_getSize() != 1)
39                 {
40                     std::wostringstream os;
41                     os << _W("Can not assign multiple value in a single variable") << std::endl;
42                     //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
43                     throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
44                 }
45
46                 pIT = result_get();
47                 //reset result
48                 result_set(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->name_get());
67                 }
68
69                 result_set(NULL);
70                 return;
71             }
72
73             if (e.right_exp_get().is_return_exp())
74             {
75                 //ReturnExp so, put the value in the previous scope
76                 symbol::Context::getInstance()->putInPreviousScope(pVar->stack_get(), pIT);
77                 ((AssignExp*)&e)->return_set();
78             }
79             else
80             {
81                 symbol::Context::getInstance()->put(pVar->stack_get(), pIT);
82             }
83
84             if (e.is_verbose() && ConfigVariable::isPromptShow())
85             {
86                 std::wostringstream ostr;
87                 ostr << pVar->name_get().name_get() << L"  = " << std::endl << std::endl;
88                 scilabWriteW(ostr.str().c_str());
89                 VariableToString(pIT, pVar->name_get().name_get().c_str());
90             }
91             return;
92         }
93
94         CellCallExp *pCell = dynamic_cast<CellCallExp*>(&e.left_exp_get());
95         if (pCell)
96         {
97             InternalType *pOut  = NULL;
98
99             /*getting what to assign*/
100             InternalType* pITR = e.right_val_get();
101             if (pITR == NULL)
102             {
103                 e.right_exp_get().accept(*this);
104                 pITR = result_get();
105                 //reset result
106                 result_set(NULL);
107             }
108
109             if (pITR == NULL)
110             {
111                 // if the right hand is NULL.
112                 std::wostringstream os;
113                 os << _W("Unable to extract right part expression.\n");
114                 throw ast::ScilabError(os.str(), 999, e.left_exp_get().location_get());
115             }
116
117             std::list<ExpHistory*> fields;
118             if (getFieldsFromExp(pCell, fields) == false)
119             {
120                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
121                 {
122                     delete *i;
123                 }
124                 std::wostringstream os;
125                 os << _W("Get fields from expression failed.");
126                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
127             }
128
129             pOut = evaluateFields(pCell, fields, pITR);
130             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
131             {
132                 delete *i;
133             }
134
135             if (pOut == NULL)
136             {
137                 std::wostringstream os;
138                 os << _W("Fields evaluation failed.");
139                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
140             }
141
142             if (pOut != NULL)
143             {
144                 if (e.is_verbose() && ConfigVariable::isPromptShow())
145                 {
146                     std::wostringstream ostr;
147                     const wchar_t* wcsVarName;
148                     if (pVar)
149                     {
150                         ostr << pVar->name_get().name_get() << L"  = " << std::endl;
151                         wcsVarName = pVar->name_get().name_get().c_str();
152                     }
153                     else
154                     {
155                         ostr << L"???" << L"  = " << std::endl;
156                         wcsVarName = L"???";
157                     }
158
159                     ostr << std::endl;
160                     VariableToString(pOut, wcsVarName);
161                 }
162             }
163             else
164             {
165                 //manage error
166                 std::wostringstream os;
167                 os << _W("Invalid Index.\n");
168                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
169             }
170
171             return;
172         }
173
174         CallExp *pCall = dynamic_cast<CallExp*>(&e.left_exp_get());
175         if (pCall)
176         {
177             //x(?) = ?
178             InternalType *pOut  = NULL;
179
180             /*getting what to assign*/
181             InternalType* pITR = e.right_val_get();
182             if (pITR == NULL)
183             {
184                 e.right_exp_get().accept(*this);
185                 pITR = result_get();
186                 //reset result
187                 result_set(NULL);
188             }
189
190             if (pITR == NULL)
191             {
192                 // if the right hand is NULL.
193                 std::wostringstream os;
194                 os << _W("Unable to extract right part expression.\n");
195                 throw ast::ScilabError(os.str(), 999, e.left_exp_get().location_get());
196             }
197
198             std::list<ExpHistory*> fields;
199             if (getFieldsFromExp(pCall, fields) == false)
200             {
201                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
202                 {
203                     delete *i;
204                 }
205                 std::wostringstream os;
206                 os << _W("Get fields from expression failed.");
207                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
208             }
209
210             pOut = evaluateFields(pCall, fields, pITR);
211             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
212             {
213                 delete *i;
214             }
215
216             if (pOut == NULL)
217             {
218                 std::wostringstream os;
219                 os << _W("Fields evaluation failed.");
220                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
221             }
222
223             if (e.is_verbose() && ConfigVariable::isPromptShow())
224             {
225                 std::wostringstream ostr;
226                 const wchar_t* wcsVarName;
227
228                 ostr << *getStructNameFromExp(&pCall->name_get()) << L"  = " << std::endl;
229                 wcsVarName = getStructNameFromExp(&pCall->name_get())->c_str();
230
231                 ostr << std::endl;
232                 scilabWriteW(ostr.str().c_str());
233                 VariableToString(pOut, wcsVarName);
234             }
235
236             pITR->killMe();
237
238             result_clear();
239             return;
240         }
241
242         AssignListExp *pList = dynamic_cast<AssignListExp*>(&e.left_exp_get());
243         if (pList)
244         {
245             //[x,y] = ?
246             int iLhsCount = (int)pList->exps_get().size();
247
248             /*getting what to assign*/
249             T exec;
250             exec.expected_setSize(iLhsCount);
251             e.right_exp_get().accept(exec);
252
253             if (exec.result_getSize() != iLhsCount)
254             {
255                 std::wostringstream os;
256                 os << _W("Incompatible assignation: trying to assign ") << exec.result_getSize();
257                 os << _W(" values in ") << iLhsCount << _W(" variables.") << std::endl;
258                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
259             }
260
261             std::list<Exp *>::const_reverse_iterator it;
262             int i = (int)iLhsCount - 1;
263             for (it = pList->exps_get().rbegin() ; it != pList->exps_get().rend() ; it++, i--)
264             {
265                 //create a new AssignExp and run it
266                 types::InternalType* pIT = exec.result_get(i);
267                 //protect temporary result from delete
268                 pIT->IncreaseRef();
269                 AssignExp pAssign((*it)->location_get(), *(*it), *const_cast<Exp*>(&e.right_exp_get()), pIT);
270                 pAssign.set_lr_owner(false);
271                 pAssign.set_verbose(e.is_verbose());
272                 pAssign.accept(*this);
273                 //unprotect temporary result
274                 pIT->DecreaseRef();
275                 //clear result to take care of [n,n]
276                 exec.result_set(i, NULL);
277             }
278             exec.result_clear();
279             return;
280         }
281
282         FieldExp *pField = dynamic_cast<FieldExp*>(&e.left_exp_get());
283         if (pField)
284         {
285             //a.b = x
286             //a.b can be a struct or a tlist/mlist or a handle
287             /*getting what to assign*/
288             expected_setSize(1);
289             e.right_exp_get().accept(*this);
290             InternalType *pIT = result_get();
291             if (pIT->isImplicitList())
292             {
293                 if (pIT->getAs<ImplicitList>()->isComputable())
294                 {
295                     InternalType *pTemp = pIT->getAs<ImplicitList>()->extractFullMatrix();
296                     delete pIT;
297                     result_set(NULL);
298                     pIT = pTemp;
299                 }
300             }
301
302             std::list<ExpHistory*> fields;
303             if (getFieldsFromExp(pField, fields) == false)
304             {
305                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
306                 {
307                     delete *i;
308                 }
309                 std::wostringstream os;
310                 os << _W("Get fields from expression failed.");
311                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
312             }
313
314             if (evaluateFields(pField, fields, pIT) == NULL)
315             {
316                 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
317                 {
318                     delete *i;
319                 }
320                 std::wostringstream os;
321                 os << _W("Fields evaluation failed.");
322                 throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
323             }
324
325             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
326             {
327                 delete *i;
328             }
329
330             if (e.is_verbose() && ConfigVariable::isPromptShow())
331             {
332                 const wstring *pstName = getStructNameFromExp(pField);
333
334                 types::InternalType* pPrint = symbol::Context::getInstance()->get(symbol::Symbol(*pstName));
335                 std::wostringstream ostr;
336                 ostr << *pstName << L"  = " << std::endl << std::endl;
337                 scilabWriteW(ostr.str().c_str());
338                 VariableToString(pPrint, pstName->c_str());
339             }
340
341             result_clear();
342             return;
343         }
344
345         std::wostringstream os;
346         os << _W("unknow script form");
347         //os << ((Location)e.right_exp_get().location_get()).location_getString() << std::endl;
348         throw ast::ScilabError(os.str(), 999, e.right_exp_get().location_get());
349     }
350     catch (ast::ScilabError error)
351     {
352         throw error;
353     }
354 }