2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 //file included in runvisitor.cpp
20 void RunVisitorT<T>::visitprivate(const CallExp &e)
22 CoverageInstance::invokeAndStartChrono((void*)&e);
23 types::typed_list outTmp;
24 types::typed_list inTmp;
25 std::vector<std::wstring> vectOptName;
26 std::vector<int> vectNbResult;
28 int iRetCount = getExpectedSize();
29 int iSaveExpectedSize = iRetCount;
31 //get function arguments
32 exps_t args = e.getArgs();
35 for (auto& arg : args)
37 int iSize = getExpectedSize();
38 if (arg->isAssignExp())
40 AssignExp* pAssign = static_cast<AssignExp*>(arg);
42 Exp* pL = &pAssign->getLeftExp();
43 if (!pL->isSimpleVar())
45 std::wostringstream os;
46 os << _W("left side of optional parameter must be a variable") << std::endl;
47 CoverageInstance::stopChrono((void*)&e);
48 throw ast::InternalError(os.str(), 999, e.getLocation());
51 SimpleVar* pVar = pL->getAs<SimpleVar>();
52 Exp* pR = &pAssign->getRightExp();
53 // optional parameter have only one output argument
59 catch (ScilabException &)
61 CoverageInstance::stopChrono((void*)&e);
64 setExpectedSize(iSize);
65 types::InternalType* pITR = getResult();
66 // IncreaseRef to protect opt argument of scope_end delete
67 // It will be deleted by clear_opt
70 vectOptName.push_back(pVar->getSymbol().getName());
71 inTmp.push_back(pITR);
72 vectNbResult.push_back(1);
83 catch (ScilabException &)
85 CoverageInstance::stopChrono((void*)&e);
88 setExpectedSize(iSize);
90 if (getResult() == NULL)
92 //special case for empty extraction of list ( list()(:) )
93 vectNbResult.push_back(0);
99 inTmp.push_back(getResult());
100 getResult()->IncreaseRef();
104 for (int i = 0; i < getResultSize(); i++)
106 types::InternalType * pITArg = getResult(i);
107 pITArg->IncreaseRef();
108 inTmp.push_back(pITArg);
112 vectNbResult.push_back(getResultSize());
116 catch (const InternalError& ie)
119 cleanIn(inTmp, outTmp);
120 CoverageInstance::stopChrono((void*)&e);
124 // get function/variable
127 e.getName().accept(*this);
129 catch (ScilabException &)
131 CoverageInstance::stopChrono((void*)&e);
134 types::InternalType* pIT = getResult();
136 // pIT can be NULL if one of call return nothing. foo()(1) with foo return nothing.
140 std::wostringstream os;
141 os << _W("Cannot extract from nothing.") << std::endl;
142 CoverageInstance::stopChrono((void*)&e);
143 throw ast::InternalError(os.str(), 999, e.getLocation());
146 types::typed_list out;
147 types::typed_list in;
148 types::optional_list opt;
150 // manage case [a,b]=foo() where foo is defined as a=foo()
151 if (pIT->getInvokeNbOut() != -1 && pIT->getInvokeNbOut() < iRetCount)
154 std::wostringstream os;
155 os << _W("Wrong number of output arguments.\n") << std::endl;
156 CoverageInstance::stopChrono((void*)&e);
157 throw ast::InternalError(os.str(), 999, e.getLocation());
160 if (pIT->isCallable())
162 CoverageInstance::invoke(static_cast<types::Callable *>(pIT));
165 // manage input according the function/variable
169 for (auto& arg : args)
173 //special case for empty extraction of list ( list()(:) )
174 if (vectNbResult[iLoop] == 0)
179 //extract implicit list for call()
180 if (pIT->isCallable() || pIT->isUserType())
182 if (inTmp[iterIn]->isImplicitList())
184 types::ImplicitList* pIL = inTmp[iterIn]->getAs<types::ImplicitList>();
185 if (pIL->isComputable())
187 types::InternalType* pITExtract = pIL->extractFullMatrix();
188 pITExtract->IncreaseRef();
189 inTmp[iterIn] = pITExtract;
196 // management of optional input
197 if (arg->isAssignExp())
199 if (pIT->hasInvokeOption())
201 opt[vectOptName[iterOptName++]] = inTmp[iterIn++];
203 //in case of macro/macrofile, we have to shift input param
204 //so add NULL item in in list to keep initial order
205 if (pIT->isMacro() || pIT->isMacroFile())
212 in.push_back(inTmp[iterIn++]);
219 for (int i = 0; i < vectNbResult[iLoop]; i++, iterIn++)
221 in.push_back(inTmp[iterIn]);
227 // Extraction with a List in input argument.
228 // This extraction must be a recursive extract.
230 types::List* pListArg = NULL;
231 if (pIT->isCallable() == false && in.size() == 1 && in[0]->isList())
233 pListArg = in[0]->getAs<types::List>();
234 iLoopSize = pListArg->getSize();
238 setExpectedSize(iSaveExpectedSize);
239 iRetCount = std::max(1, iRetCount);
241 for (int i = 0; i < iLoopSize; i++)
245 in[0] = pListArg->get(i);
249 if (pIT->isCallable())
251 // list used like "varargin"
252 types::List* pLFuncArgs = in[0]->getAs<types::List>();
253 types::typed_list input;
254 for (int j = 0; j < pLFuncArgs->getSize(); j++)
256 input.push_back(pLFuncArgs->get(j));
257 input.back()->IncreaseRef();
264 pListArg->DecreaseRef();
267 std::wostringstream os;
268 os << _W("Invalid index.\n");
269 throw ast::InternalError(os.str(), 999, e.getFirstLocation());
274 in[0]->IncreaseRef();
279 if (pIT->isInvokable() == false)
282 ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, this);
286 ret = pIT->invoke(in, opt, iRetCount, out, e);
287 if (ret == false && pIT->isUserType())
290 ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, this);
296 if (iSaveExpectedSize != -1 && iSaveExpectedSize > out.size())
299 if (pIT->isCallable())
301 char* strFName = wide_string_to_UTF8(pIT->getAs<types::Callable>()->getName().c_str());
302 os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), strFName, out.size());
307 os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), "extract", out.size());
310 wchar_t* wError = to_wide_string(szError);
311 std::wstring err(wError);
313 throw InternalError(err, 999, e.getLocation());
316 setExpectedSize(iSaveExpectedSize);
321 // In case a.b(), getResult contain pIT ("b").
322 // If out == pIT, do not delete it.
323 if (getResult() != pIT)
325 // protect element of out in case where
326 // out contain elements of pIT
327 for (int i = 0; i < out.size(); i++)
329 out[i]->IncreaseRef();
335 for (int i = 0; i < out.size(); i++)
337 out[i]->DecreaseRef();
341 if (pListArg && i + 1 != iLoopSize)
350 std::wostringstream os;
351 os << _W("Invalid index.\n");
352 throw ast::InternalError(os.str(), 999, e.getFirstLocation());
358 pListArg->DecreaseRef();
362 catch (InternalAbort & ia)
364 setExpectedSize(iSaveExpectedSize);
365 if (pIT != getResult())
373 CoverageInstance::stopChrono((void*)&e);
377 catch (const InternalError& ie)
379 setExpectedSize(iSaveExpectedSize);
380 if (pIT != getResult())
388 CoverageInstance::stopChrono((void*)&e);
393 CoverageInstance::stopChrono((void*)&e);
397 void RunVisitorT<T>::visitprivate(const CellCallExp &e)
399 CoverageInstance::invokeAndStartChrono((void*)&e);
405 e.getName().accept(execMeCell);
407 catch (ScilabException &)
409 CoverageInstance::stopChrono((void*)&e);
413 if (execMeCell.getResult() != NULL)
415 //a{xxx} with a variable, extraction
416 types::InternalType *pIT = NULL;
418 pIT = execMeCell.getResult();
423 if (pIT->isCell() == false)
425 CoverageInstance::stopChrono((void*)&e);
426 throw ast::InternalError(_W("[error] Cell contents reference from a non-cell array object.\n"), 999, e.getFirstLocation());
428 //Create list of indexes
429 ast::exps_t exps = e.getArgs();
430 types::typed_list *pArgs = GetArgumentList(exps);
432 if (pArgs->size() == 0)
436 std::wostringstream os;
437 os << _W("Cell : Cannot extract without arguments.\n");
438 CoverageInstance::stopChrono((void*)&e);
439 throw ast::InternalError(os.str(), 999, e.getFirstLocation());
442 types::List* pList = pIT->getAs<types::Cell>()->extractCell(pArgs);
447 std::wostringstream os;
448 os << _W("inconsistent row/column dimensions\n");
449 //os << ((*e.args_get().begin())->getLocation()).getLocationString() << std::endl;
450 CoverageInstance::stopChrono((void*)&e);
451 throw ast::InternalError(os.str(), 999, e.getFirstLocation());
454 if (pList->getSize() == 1)
456 types::InternalType* ret = pList->get(0);
469 //clean pArgs return by GetArgumentList
470 for (int iArg = 0; iArg < (int)pArgs->size(); iArg++)
472 (*pArgs)[iArg]->killMe();
479 //result == NULL ,variable doesn't exist :(
480 // Should never be in this case
481 // In worst case variable pointing to function does not exists
482 // visitprivate(SimpleVar) will throw the right exception.
484 CoverageInstance::stopChrono((void*)&e);
487 } /* namespace ast */