2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
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
13 //file included in runvisitor.cpp
17 void RunVisitorT<T>::visitprivate(const AssignExp &e)
19 symbol::Context* ctx = symbol::Context::getInstance();
20 /*Create local exec visitor*/
23 SimpleVar * pVar = NULL;
24 if (e.getLeftExp().isSimpleVar())
26 pVar = static_cast<SimpleVar*>(&e.getLeftExp());
29 /*get king of left hand*/
33 /*getting what to assign*/
34 types::InternalType *pIT = e.getRightVal();
38 e.getRightExp().accept(*this);
40 if (getResultSize() != 1)
42 std::wostringstream os;
43 os << _W("Can not assign multiple value in a single variable") << std::endl;
44 //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
45 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
53 if (pIT->isImplicitList())
55 if (pIT->getAs<types::ImplicitList>()->isComputable())
57 types::InternalType *pTemp = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
63 if (pIT->isAssignable() == false)
65 if (pIT->isListDelete())
67 //used to delete a variable in current scope
68 symbol::Symbol sym = pVar->getSymbol();
69 if (ctx->isprotected(sym) == false)
75 std::wostringstream os;
76 os << _W("Redefining permanent variable.\n");
77 throw ast::InternalError(os.str(), 999, e.getLeftExp().getLocation());
85 if (pIT->isList() && pIT->getRef() > 0)
87 // Prevent modification of all scilab variable
88 // which point to this container when it is used
89 // in setfield scilab function.
90 // A clone on a container will not clone what it contain.
94 if (e.getRightExp().isReturnExp())
96 //ReturnExp so, put the value in the previous scope
97 ctx->putInPreviousScope(pVar->getStack(), pIT);
98 ((AssignExp*)&e)->setReturn();
102 if (ctx->isprotected(pVar->getStack()) == false)
104 ctx->put(pVar->getStack(), pIT);
108 std::wostringstream os;
109 os << _W("Redefining permanent variable.\n");
110 throw ast::InternalError(os.str(), 999, e.getLeftExp().getLocation());
114 if (e.isVerbose() && ConfigVariable::isPromptShow())
116 std::wstring wstrName = pVar->getSymbol().getName();
117 std::wostringstream ostr;
118 ostr << L" " << wstrName << L" = " << std::endl << std::endl;
119 scilabWriteW(ostr.str().c_str());
120 std::wostringstream ostrName;
121 ostrName << wstrName;
122 VariableToString(pIT, ostrName.str().c_str());
127 if (e.getLeftExp().isCellCallExp())
129 CellCallExp *pCell = static_cast<CellCallExp*>(&e.getLeftExp());
130 types::InternalType *pOut = NULL;
132 /*getting what to assign*/
133 types::InternalType* pITR = e.getRightVal();
136 e.getRightExp().accept(*this);
144 // if the right hand is NULL.
145 std::wostringstream os;
146 os << _W("Unable to extract right part expression.\n");
147 throw ast::InternalError(os.str(), 999, e.getLeftExp().getLocation());
150 std::list<ExpHistory*> fields;
151 if (getFieldsFromExp(pCell, fields) == false)
153 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
157 std::wostringstream os;
158 os << _W("Get fields from expression failed.");
159 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
164 pOut = evaluateFields(pCell, fields, pITR);
166 catch (const InternalError& error)
168 // catch error when call overload
169 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
171 (*i)->setDeleteCurrent(true);
179 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
188 std::wostringstream os;
189 os << _W("Fields evaluation failed.");
190 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
195 if (e.isVerbose() && ConfigVariable::isPromptShow())
197 std::wostringstream ostr;
198 ostr << L" " << *getStructNameFromExp(pCell) << L" = " << std::endl;
200 scilabWriteW(ostr.str().c_str());
202 VariableToString(pOut, ostr.str().c_str());
208 std::wostringstream os;
209 os << _W("Invalid Index.\n");
210 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
216 if (e.getLeftExp().isCallExp())
218 CallExp *pCall = static_cast<CallExp*>(&e.getLeftExp());
220 types::InternalType *pOut = NULL;
222 /*getting what to assign*/
223 types::InternalType* pITR = e.getRightVal();
226 e.getRightExp().accept(*this);
234 // if the right hand is NULL.
235 std::wostringstream os;
236 os << _W("Unable to extract right part expression.\n");
237 throw ast::InternalError(os.str(), 999, e.getLeftExp().getLocation());
240 bool alreadyProcessed = false;
241 //a(...) without fields or whatever on arrayof derived types
242 if (pCall->getName().isSimpleVar())
244 ast::SimpleVar* var = pCall->getName().getAs<ast::SimpleVar>();
245 types::InternalType* pIT = ctx->getCurrentLevel(var->getStack());
246 if (pIT && pIT->isArrayOf())
248 if (ctx->isprotected(var->getStack()))
250 std::wostringstream os;
251 os << _W("Redefining permanent variable.\n");
252 throw ast::InternalError(os.str(), 999, pCall->getLocation());
255 // prevent delete after extractFullMatrix
256 // called in insertionCall when pITR is an ImplicitList
259 types::typed_list* currentArgs = GetArgumentList(pCall->getArgs());
263 pOut = insertionCall(e, currentArgs, pIT, pITR);
265 catch (const InternalError& error)
268 // call killMe on all arguments
269 cleanOut(*currentArgs);
271 // insertion have done, call killMe on pITR
278 // call killMe on all arguments
279 cleanOut(*currentArgs);
282 // insertion have done, call killMe on pITR
287 std::wostringstream os;
288 os << _W("Submatrix incorrectly defined.\n");
289 throw ast::InternalError(os.str(), 999, e.getLocation());
293 //update variable with new value
296 ctx->put(var->getStack(), pOut);
299 alreadyProcessed = true;
303 if (alreadyProcessed == false)
305 std::list<ExpHistory*> fields;
306 if (getFieldsFromExp(pCall, fields) == false)
308 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
313 std::wostringstream os;
314 os << _W("Instruction left hand side: waiting for a name.");
315 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
318 // prevent delete after extractFullMatrix
319 // called in evaluateFields when pITR is an ImplicitList
324 pOut = evaluateFields(pCall, fields, pITR);
326 catch (const InternalError& error)
328 // catch error when call overload
329 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
340 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
350 std::wostringstream os;
351 os << _W("Fields evaluation failed.");
352 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
356 if (e.isVerbose() && ConfigVariable::isPromptShow())
358 std::wostringstream ostr;
359 ostr << L" " << *getStructNameFromExp(&pCall->getName()) << L" = " << std::endl;
361 scilabWriteW(ostr.str().c_str());
363 std::wostringstream ostrName;
364 ostrName << *getStructNameFromExp(&pCall->getName());
365 VariableToString(pOut, ostrName.str().c_str());
372 if (e.getLeftExp().isAssignListExp())
374 AssignListExp *pList = e.getLeftExp().getAs<AssignListExp>();
376 int iLhsCount = (int)pList->getExps().size();
378 /*getting what to assign*/
380 exec.setExpectedSize(iLhsCount);
381 e.getRightExp().accept(exec);
383 if (exec.getResultSize() < iLhsCount)
385 std::wostringstream os;
386 os << _W("Incompatible assignation: trying to assign ") << exec.getResultSize();
387 os << _W(" values in ") << iLhsCount << _W(" variables.") << std::endl;
388 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
391 exps_t::const_reverse_iterator it;
392 exps_t exps = pList->getExps();
393 types::InternalType** pIT = new types::InternalType*[iLhsCount];
395 for (i = iLhsCount - 1; i >= 0; i--)
397 //create a new AssignExp and run it
398 pIT[i] = (exec.getResult(i));
399 //protet rhs against removal [a,b] = (b,a);
400 pIT[i]->IncreaseRef();
403 for (i = iLhsCount - 1, it = exps.rbegin(); it != exps.rend(); it++, i--)
405 Exp* pExp = e.getRightExp().clone();
406 AssignExp pAssign((*it)->getLocation(), *(*it), *pExp, pIT[i]);
407 pAssign.setLrOwner(false);
408 pAssign.setVerbose(e.isVerbose());
409 pAssign.accept(*this);
410 //clear result to take care of [n,n]
411 exec.setResult(i, NULL);
415 for (i = iLhsCount - 1; i >= 0; i--)
418 pIT[i]->DecreaseRef();
427 if (e.getLeftExp().isFieldExp())
429 FieldExp *pField = static_cast<FieldExp*>(&e.getLeftExp());
430 types::InternalType *pIT = e.getRightVal();
434 //a.b can be a struct or a tlist/mlist or a handle
435 /*getting what to assign*/
437 e.getRightExp().accept(*this);
442 if (pIT->isImplicitList())
444 if (pIT->getAs<types::ImplicitList>()->isComputable())
446 types::InternalType *pTemp = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
453 std::list<ExpHistory*> fields;
454 if (getFieldsFromExp(pField, fields) == false)
456 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
460 std::wostringstream os;
461 os << _W("Get fields from expression failed.");
462 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
467 if (evaluateFields(pField, fields, pIT) == NULL)
469 for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
473 std::wostringstream os;
474 os << _W("Fields evaluation failed.");
475 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
478 catch (const InternalError& error)
480 for (auto i : fields)
488 for (auto i : fields)
493 if (e.isVerbose() && ConfigVariable::isPromptShow())
495 const std::wstring *pstName = getStructNameFromExp(pField);
497 types::InternalType* pPrint = ctx->get(symbol::Symbol(*pstName));
498 std::wostringstream ostr;
499 ostr << L" " << *pstName << L" = " << std::endl << std::endl;
500 scilabWriteW(ostr.str().c_str());
502 std::wostringstream ostrName;
503 ostrName << *pstName;
504 VariableToString(pPrint, ostrName.str().c_str());
511 std::wostringstream os;
512 os << _W("unknow script form");
513 //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
514 throw ast::InternalError(os.str(), 999, e.getRightExp().getLocation());
516 catch (const InternalError& error)
522 } /* namespace ast */