2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
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 // This code is separated in run_CallExp.hxx
14 // but will be inlined in runvisitor.hxx
15 // using #include with RunVisitorT class declaration.
17 // If you need additionnal headers, please add it in runvisitor.hxx
19 void visitprivate(const CallExp &e)
21 std::list<Exp *>::const_iterator itExp;
23 e.name_get().accept(*this);
24 if (result_get() != NULL && result_get()->isCallable())
27 types::InternalType* pIT = result_get();
28 types::Callable *pCall = pIT->getAs<types::Callable>();
29 types::typed_list out;
31 types::optional_list opt;
33 int iRetCount = expected_getSize();
35 //get function arguments
36 for (itExp = e.args_get().begin (); itExp != e.args_get().end (); ++itExp)
38 AssignExp* pAssign = dynamic_cast<AssignExp*>(*itExp);
42 Exp* pL = &pAssign->left_exp_get();
43 SimpleVar* pVar = dynamic_cast<SimpleVar*>(pL);
46 std::wostringstream os;
47 os << _W("left side of optional parameter must be a variable") << std::endl;
48 throw ScilabError(os.str(), 999, e.location_get());
51 Exp* pR = &pAssign->right_exp_get();
53 InternalType* pITR = result_get();
55 opt.push_back(std::pair<std::wstring, InternalType*>(pVar->name_get().name_get(), pITR));
56 //in case of macro/macrofile, we have to shift input param
57 //so add NULL item in in list to keep initial order
58 if (pIT->isMacro() || pIT->isMacroFile())
66 (*itExp)->accept (*this);
68 if (result_get() == NULL)
70 //special case for empty extraction of list ( list()(:) )
75 if (result_get()->isImplicitList())
77 types::ImplicitList* pIL = pIT->getAs<types::ImplicitList>();
78 if (pIL->isComputable() == false)
80 types::Double* pVal = new types::Double(-1, -1);
81 pVal->getReal()[0] = 1;
86 result_set(pIL->extractFullMatrix());
90 if (is_single_result())
92 in.push_back(result_get());
93 result_get()->IncreaseRef();
97 for (int i = 0 ; i < result_getSize() ; i++)
99 in.push_back(result_get(i));
100 result_get(i)->IncreaseRef();
107 int iSaveExpectedSize = iRetCount;
108 expected_size_set(iSaveExpectedSize);
109 iRetCount = Max(1, iRetCount);
111 //reset previous error before call function
112 ConfigVariable::resetError();
113 //update verbose";" flag
114 ConfigVariable::setVerbose(e.is_verbose());
116 types::Function::ReturnValue Ret = pCall->call(in, opt, iRetCount, out, this);
117 expected_size_set(iSaveExpectedSize);
120 if (Ret == types::Callable::OK)
122 if (expected_getSize() == 1 && out.size() == 0) //some function have no returns
124 if (static_cast<int>(out.size()) < iRetCount)
126 //clear input parameters
127 for (unsigned int k = 0; k < in.size(); k++)
134 in[k]->DecreaseRef();
135 if (in[k]->isDeletable())
141 std::wostringstream os;
142 os << _W("bad lhs, expected : ") << iRetCount << _W(" returned : ") << out.size() << std::endl;
143 throw ScilabError(os.str(), 999, e.location_get());
153 for (int i = 0 ; i < static_cast<int>(out.size()) ; i++)
155 result_set(i, out[i]);
159 else if (Ret == types::Callable::Error)
161 ConfigVariable::setLastErrorFunction(pCall->getName());
162 ConfigVariable::setLastErrorLine(e.location_get().first_line);
166 catch (ScilabMessage sm)
168 //clear input parameters
169 for (unsigned int k = 0; k < in.size(); k++)
171 if (in[k] && in[k]->isDeletable())
177 if (pCall->isMacro() || pCall->isMacroFile())
179 wchar_t szError[bsiz];
180 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n"), sm.GetErrorLocation().first_line, pCall->getName().c_str());
181 throw ScilabMessage(szError);
189 //clear input parameters but take care in case of in[k] == out[i]
190 for (unsigned int k = 0; k < in.size(); k++)
197 //check if input data are use as output data
199 for (int i = 0 ; i < out.size() ; i++)
208 in[k]->DecreaseRef();
211 if (in[k]->isDeletable())
218 else if (result_get() != NULL)
220 //a(xxx) with a variable, extraction
222 //get symbol of variable
223 types::InternalType *pIT = NULL;
225 //WARNING can be a fieldexp
226 const SimpleVar *Var = dynamic_cast<const SimpleVar*>(&e.name_get());
229 pIT = symbol::Context::getInstance()->get(Var->name_get());
236 int iArgDim = static_cast<int>(e.args_get().size());
237 types::InternalType *pOut = NULL;
238 std::vector<types::InternalType*> ResultList;
240 //To manage extraction without parameter like SCI()
248 //Create list of indexes
249 types::typed_list *pArgs = GetArgumentList(e.args_get());
251 switch (pIT->getType())
253 case types::InternalType::RealDouble :
254 pOut = pIT->getAs<types::Double>()->extract(pArgs);
256 case types::InternalType::RealString :
257 pOut = pIT->getAs<types::String>()->extract(pArgs);
259 case types::InternalType::RealBool :
260 pOut = pIT->getAs<types::Bool>()->extract(pArgs);
262 case types::InternalType::RealPoly :
263 pOut = pIT->getAs<types::Polynom>()->extract(pArgs);
265 case types::InternalType::RealInt8 :
266 pOut = pIT->getAs<types::Int8>()->extract(pArgs);
268 case types::InternalType::RealUInt8 :
269 pOut = pIT->getAs<types::UInt8>()->extract(pArgs);
271 case types::InternalType::RealInt16 :
272 pOut = pIT->getAs<types::Int16>()->extract(pArgs);
274 case types::InternalType::RealUInt16 :
275 pOut = pIT->getAs<types::UInt16>()->extract(pArgs);
277 case types::InternalType::RealInt32 :
278 pOut = pIT->getAs<types::Int32>()->extract(pArgs);
280 case types::InternalType::RealUInt32 :
281 pOut = pIT->getAs<types::UInt32>()->extract(pArgs);
283 case types::InternalType::RealInt64 :
284 pOut = pIT->getAs<types::Int64>()->extract(pArgs);
286 case types::InternalType::RealUInt64 :
287 pOut = pIT->getAs<types::UInt64>()->extract(pArgs);
289 case types::InternalType::RealList :
291 ResultList = pIT->getAs<types::List>()->extract(pArgs);
293 switch (ResultList.size())
301 result_set(ResultList[0]);
304 for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
306 result_set(i, ResultList[i]);
312 case InternalType::RealTList :
314 bool bCallOverLoad = false;
315 if (pArgs->size() == 1)
317 types::InternalType* pArg = (*pArgs)[0];
318 if ( pArg->isDouble() ||
321 pArg->isImplicitList() ||
326 //call "normal" extract
328 iField.push_back(pArg);
329 ResultList = pIT->getAs<TList>()->extract(&iField);
331 else if (pArg->isString())
334 list<wstring> stFields;
335 String *pString = (*pArgs)[0]->getAs<types::String>();
336 for (int i = 0 ; i < pString->getSize() ; i++)
338 stFields.push_back(pString->get(i));
341 ResultList = pIT->getAs<TList>()->extractStrings(stFields);
342 if (ResultList.empty())
344 bCallOverLoad = true;
349 bCallOverLoad = true;
354 bCallOverLoad = true;
359 types::typed_list in;
361 //create input argument list
364 for (int i = 0 ; i < pArgs->size() ; i++)
366 (*pArgs)[i]->IncreaseRef();
367 in.push_back((*pArgs)[i]);
376 //try to call specific exrtaction function
377 Overload::call(L"%" + pIT->getAs<TList>()->getShortTypeStr() + L"_e", in, 1, ResultList, this);
379 catch (ScilabError /*&e*/)
381 //if call failed try to call generic extraction function
382 Overload::call(L"%l_e", in, 1, ResultList, this);
385 for (int i = 0 ; i < pArgs->size() ; i++)
387 (*pArgs)[i]->DecreaseRef();
392 switch (ResultList.size())
396 std::wostringstream os;
397 os << _W("Invalid index.\n");
398 throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
402 result_set(ResultList[0]);
405 for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
407 result_set(i, ResultList[i]);
413 case InternalType::RealMList :
415 bool bCallOverLoad = false;
416 if (pArgs->size() == 1)
418 types::InternalType* pArg = (*pArgs)[0];
419 if (pArg->isString())
422 list<wstring> stFields;
423 String *pString = (*pArgs)[0]->getAs<types::String>();
424 for (int i = 0 ; i < pString->getSize() ; i++)
426 stFields.push_back(pString->get(i));
429 ResultList = pIT->getAs<MList>()->extractStrings(stFields);
430 if (ResultList.empty())
432 bCallOverLoad = true;
437 bCallOverLoad = true;
442 bCallOverLoad = true;
447 types::typed_list in;
449 //create input argument list
452 for (int i = 0 ; i < pArgs->size() ; i++)
454 (*pArgs)[i]->IncreaseRef();
455 in.push_back((*pArgs)[i]);
464 //try to call specific exrtaction function
465 Overload::call(L"%" + pIT->getAs<MList>()->getShortTypeStr() + L"_e", in, 1, ResultList, this);
467 catch (ScilabError /*&e*/)
469 //if call failed try to call generic extraction function
470 Overload::call(L"%l_e", in, 1, ResultList, this);
473 for (int i = 0 ; i < pArgs->size() ; i++)
475 (*pArgs)[i]->DecreaseRef();
480 switch (ResultList.size())
484 std::wostringstream os;
485 os << _W("Invalid index.\n");
486 throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
490 result_set(ResultList[0]);
493 for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
495 result_set(i, ResultList[i]);
501 case InternalType::RealCell :
502 pOut = pIT->getAs<Cell>()->extract(pArgs);
504 case types::InternalType::RealSparse :
505 pOut = pIT->getAs<types::Sparse>()->extract(pArgs);
507 case types::InternalType::RealSparseBool :
508 pOut = pIT->getAs<types::SparseBool>()->extract(pArgs);
510 case types::InternalType::RealStruct :
512 types::Struct* pStr = pIT->getAs<types::Struct>();
513 if (pArgs->size() == 1 && (*pArgs)[0]->isString())
516 std::list<wstring> wstFields;
517 types::String *pS = (*pArgs)[0]->getAs<types::String>();
518 for (int i = 0 ; i < pS->getSize() ; i++)
520 wstring wstField(pS->get(i));
521 if (pStr->exists(wstField))
523 wstFields.push_back(wstField);
527 wchar_t szError[bsiz];
528 os_swprintf(szError, bsiz, _W("Field \"%ls\" does not exists\n"), wstField.c_str());
529 throw ScilabError(szError, 999, (*e.args_get().begin())->location_get());
533 ResultList = pStr->extractFields(wstFields);
534 if (ResultList.size() == 1 && ResultList[0]->getAs<types::List>()->getSize() == 1)
536 result_set(ResultList[0]->getAs<types::List>()->get(0));
540 for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
542 result_set(i, ResultList[i]);
549 pOut = pIT->getAs<types::Struct>()->extract(pArgs);
553 case types::InternalType::RealHandle :
555 if (pArgs->size() == 1 && (*pArgs)[0]->isString())
558 types::GraphicHandle* pH = pIT->getAs<types::GraphicHandle>();
559 types::String *pS = (*pArgs)[0]->getAs<types::String>();
567 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"%h_e"));
568 Callable::ReturnValue ret = pCall->call(in, opt, 1, out, this);
569 if (ret == Callable::OK)
576 pOut = pIT->getAs<types::GraphicHandle>()->extract(pArgs);
584 //clean pArgs return by GetArgumentList
585 for (int iArg = 0 ; iArg < pArgs->size() ; iArg++)
587 if ((*pArgs)[iArg]->isDeletable())
589 delete (*pArgs)[iArg];
595 //List extraction can return multiple items
596 if (pIT->isList() == false && pIT->isTList() == false)
600 // Special case, try to extract from an empty matrix.
601 if (pIT->isDouble() && pIT->getAs<types::Double>()->getSize() == 0)
603 pOut = types::Double::Empty();
607 std::wostringstream os;
608 os << _W("Invalid index.\n");
609 //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
610 throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
617 if (ResultList.size() == 0)
625 std::wostringstream os;
626 os << _W("inconsistent row/column dimensions\n");
627 //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
628 throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
635 //result == NULL ,variable doesn't exist :(
636 // Sould never be in this case
637 // In worst case variable pointing to function does not exists
638 // visitprivate(SimpleVar) will throw the right exception.
642 void visitprivate(const CellCallExp &e)
646 e.name_get().accept(execMeCell);
648 if (execMeCell.result_get() != NULL)
650 //a{xxx} with a variable, extraction
651 types::InternalType *pIT = NULL;
653 pIT = execMeCell.result_get();
658 if (pIT->isCell() == false)
660 throw ScilabError(_W("[error] Cell contents reference from a non-cell array object.\n"), 999, (*e.args_get().begin())->location_get());
662 //Create list of indexes
663 types::typed_list *pArgs = GetArgumentList(e.args_get());
665 types::List* pList = pIT->getAs<types::Cell>()->extractCell(pArgs);
669 std::wostringstream os;
670 os << _W("inconsistent row/column dimensions\n");
671 //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
672 throw ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
675 if (pList->getSize() == 1)
677 result_set(pList->get(0));
684 //clean pArgs return by GetArgumentList
685 for (int iArg = 0 ; iArg < pArgs->size() ; iArg++)
687 if ((*pArgs)[iArg]->isDeletable())
689 delete (*pArgs)[iArg];
697 //result == NULL ,variable doesn't exist :(
698 // Sould never be in this case
699 // In worst case variable pointing to function does not exists
700 // visitprivate(SimpleVar) will throw the right exception.