void RunVisitorT<T>::visitprivate(const LogicalOpExp &e) { try { InternalType *pITR = NULL; //assign only in non shortcut operations. /*getting what to assign*/ e.getLeft().accept(*this); InternalType *pITL = getResult(); if (isSingleResult() == false) { std::wostringstream os; os << _W("Incompatible output argument.\n"); //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl; throw ast::InternalError(os.str(), 999, e.getRight().getLocation()); } setResult(NULL); if (pITL->getType() == GenericType::ScilabImplicitList) { ImplicitList* pIL = pITL->getAs<ImplicitList>(); if (pIL->isComputable()) { pITL = pIL->extractFullMatrix(); pIL->killMe(); } } InternalType *pResult = NULL; switch (e.getOper()) { case LogicalOpExp::logicalShortCutAnd : { pResult = GenericShortcutAnd(pITL); if (pResult) { break; } //Continue to logicalAnd } case LogicalOpExp::logicalAnd : { /*getting what to assign*/ e.getRight().accept(*this); pITR = getResult(); if (isSingleResult() == false) { std::wostringstream os; os << _W("Incompatible output argument.\n"); //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl; throw ast::InternalError(os.str(), 999, e.getRight().getLocation()); } if (pITR->getType() == GenericType::ScilabImplicitList) { ImplicitList* pIR = pITR->getAs<ImplicitList>(); if (pIR->isComputable()) { pITR = pIR->extractFullMatrix(); pIR->killMe(); } } pResult = GenericLogicalAnd(pITL, pITR); break; } case LogicalOpExp::logicalShortCutOr : { pResult = GenericShortcutOr(pITL); if (pResult) { break; } //Continue to logicalAnd } case LogicalOpExp::logicalOr : { /*getting what to assign*/ e.getRight().accept(*this); pITR = getResult(); if (isSingleResult() == false) { std::wostringstream os; os << _W("Incompatible output argument.\n"); //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl; throw ast::InternalError(os.str(), 999, e.getRight().getLocation()); } if (pITR->getType() == GenericType::ScilabImplicitList) { ImplicitList* pIR = pITR->getAs<ImplicitList>(); if (pIR->isComputable()) { pITR = pIR->extractFullMatrix(); } } pResult = GenericLogicalOr(pITL, pITR); break; } default : break; } //overloading if (pResult == NULL) { // We did not have any algorithm matching, so we try to call OverLoad pResult = callOverloadOpExp(e.getOper(), pITL, pITR); } setResult(pResult); // protect pResult in case where pITL or pITR equal pResult pResult->IncreaseRef(); //clear left and/or right operands pITL->killMe(); if (pITR) { pITR->killMe(); } // unprotect pResult pResult->DecreaseRef(); } catch (ast::InternalError& error) { clearResult(); error.SetErrorLocation(e.getLocation()); throw error; } }
void RunVisitorT<T>::visitprivate(const CallExp &e) { CoverageInstance::invokeAndStartChrono((void*)&e); types::typed_list outTmp; types::typed_list inTmp; std::vector<std::wstring> vectOptName; std::vector<int> vectNbResult; int iRetCount = getExpectedSize(); int iSaveExpectedSize = iRetCount; //get function arguments exps_t args = e.getArgs(); try { for (auto& arg : args) { int iSize = getExpectedSize(); if (arg->isAssignExp()) { AssignExp* pAssign = static_cast<AssignExp*>(arg); //optional parameter Exp* pL = &pAssign->getLeftExp(); if (!pL->isSimpleVar()) { std::wostringstream os; os << _W("left side of optional parameter must be a variable") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } SimpleVar* pVar = pL->getAs<SimpleVar>(); Exp* pR = &pAssign->getRightExp(); // optional parameter have only one output argument setExpectedSize(1); try { pR->accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } setExpectedSize(iSize); types::InternalType* pITR = getResult(); // IncreaseRef to protect opt argument of scope_end delete // It will be deleted by clear_opt pITR->IncreaseRef(); vectOptName.push_back(pVar->getSymbol().getName()); inTmp.push_back(pITR); vectNbResult.push_back(1); clearResult(); continue; } setExpectedSize(-1); try { arg->accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } setExpectedSize(iSize); if (getResult() == NULL) { //special case for empty extraction of list ( list()(:) ) vectNbResult.push_back(0); continue; } if (isSingleResult()) { inTmp.push_back(getResult()); getResult()->IncreaseRef(); } else { for (int i = 0; i < getResultSize(); i++) { types::InternalType * pITArg = getResult(i); pITArg->IncreaseRef(); inTmp.push_back(pITArg); } } vectNbResult.push_back(getResultSize()); clearResult(); } } catch (const InternalError& ie) { clearResult(); cleanIn(inTmp, outTmp); CoverageInstance::stopChrono((void*)&e); throw ie; } // get function/variable try { e.getName().accept(*this); } catch (ScilabException &) { CoverageInstance::stopChrono((void*)&e); throw; } types::InternalType* pIT = getResult(); // pIT can be NULL if one of call return nothing. foo()(1) with foo return nothing. if(pIT == NULL) { clearResult(); std::wostringstream os; os << _W("Cannot extract from nothing.") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } types::typed_list out; types::typed_list in; types::optional_list opt; // manage case [a,b]=foo() where foo is defined as a=foo() if (pIT->getInvokeNbOut() != -1 && pIT->getInvokeNbOut() < iRetCount) { clearResult(); std::wostringstream os; os << _W("Wrong number of output arguments.\n") << std::endl; CoverageInstance::stopChrono((void*)&e); throw ast::InternalError(os.str(), 999, e.getLocation()); } if (pIT->isCallable()) { CoverageInstance::invoke(static_cast<types::Callable *>(pIT)); } // manage input according the function/variable int iLoop = -1; int iterIn = 0; int iterOptName = 0; for (auto& arg : args) { iLoop++; //special case for empty extraction of list ( list()(:) ) if (vectNbResult[iLoop] == 0) { continue; } //extract implicit list for call() if (pIT->isCallable() || pIT->isUserType()) { if (inTmp[iterIn]->isImplicitList()) { types::ImplicitList* pIL = inTmp[iterIn]->getAs<types::ImplicitList>(); if (pIL->isComputable()) { types::InternalType* pITExtract = pIL->extractFullMatrix(); pITExtract->IncreaseRef(); inTmp[iterIn] = pITExtract; pIL->DecreaseRef(); pIL->killMe(); } } } // management of optional input if (arg->isAssignExp()) { if (pIT->hasInvokeOption()) { opt[vectOptName[iterOptName++]] = inTmp[iterIn++]; //in case of macro/macrofile, we have to shift input param //so add NULL item in in list to keep initial order if (pIT->isMacro() || pIT->isMacroFile()) { in.push_back(NULL); } } else { in.push_back(inTmp[iterIn++]); } continue; } // default case for (int i = 0; i < vectNbResult[iLoop]; i++, iterIn++) { in.push_back(inTmp[iterIn]); } } try { // Extraction with a List in input argument. // This extraction must be a recursive extract. int iLoopSize = 1; types::List* pListArg = NULL; if (pIT->isCallable() == false && in.size() == 1 && in[0]->isList()) { pListArg = in[0]->getAs<types::List>(); iLoopSize = pListArg->getSize(); cleanOpt(opt, out); } setExpectedSize(iSaveExpectedSize); iRetCount = std::max(1, iRetCount); for (int i = 0; i < iLoopSize; i++) { if (pListArg) { in[0] = pListArg->get(i); if (in[0]->isList()) { if (pIT->isCallable()) { // list used like "varargin" types::List* pLFuncArgs = in[0]->getAs<types::List>(); types::typed_list input; for (int j = 0; j < pLFuncArgs->getSize(); j++) { input.push_back(pLFuncArgs->get(j)); input.back()->IncreaseRef(); } in = input; } else { pListArg->DecreaseRef(); pListArg->killMe(); std::wostringstream os; os << _W("Invalid index.\n"); throw ast::InternalError(os.str(), 999, e.getFirstLocation()); } } else { in[0]->IncreaseRef(); } } bool ret = false; if (pIT->isInvokable() == false) { // call overload ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, true); } else { ret = pIT->invoke(in, opt, iRetCount, out, e); if (ret == false && pIT->isUserType()) { // call overload ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, true); } } if (ret) { if (iSaveExpectedSize != -1 && iSaveExpectedSize > out.size()) { char szError[bsiz]; if (pIT->isCallable()) { char* strFName = wide_string_to_UTF8(pIT->getAs<types::Callable>()->getName().c_str()); os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), strFName, out.size()); FREE(strFName); } else { os_sprintf(szError, _("%s: Wrong number of output argument(s): %d expected.\n"), "extract", out.size()); } wchar_t* wError = to_wide_string(szError); std::wstring err(wError); FREE(wError); throw InternalError(err, 999, e.getLocation()); } setExpectedSize(iSaveExpectedSize); setResult(out); cleanIn(in, out); cleanOpt(opt, out); // In case a.b(), getResult contain pIT ("b"). // If out == pIT, do not delete it. if (getResult() != pIT) { // protect element of out in case where // out contain elements of pIT for (int i = 0; i < out.size(); i++) { out[i]->IncreaseRef(); } pIT->killMe(); // unprotect for (int i = 0; i < out.size(); i++) { out[i]->DecreaseRef(); } } if (pListArg && i + 1 != iLoopSize) { pIT = out[0]; out.clear(); setResult(NULL); } } else { std::wostringstream os; os << _W("Invalid index.\n"); throw ast::InternalError(os.str(), 999, e.getFirstLocation()); } } if (pListArg) { pListArg->DecreaseRef(); pListArg->killMe(); } } catch (InternalAbort & ia) { setExpectedSize(iSaveExpectedSize); if (pIT != getResult()) { pIT->killMe(); } clearResult(); cleanInOut(in, out); cleanOpt(opt, out); CoverageInstance::stopChrono((void*)&e); throw ia; } catch (const InternalError& ie) { setExpectedSize(iSaveExpectedSize); if (pIT != getResult()) { pIT->killMe(); } clearResult(); cleanInOut(in, out); cleanOpt(opt, out); CoverageInstance::stopChrono((void*)&e); throw ie; } CoverageInstance::stopChrono((void*)&e); }
void RunVisitorT<T>::visitprivate(const OpExp &e) { InternalType * pITL = NULL, * pITR = NULL, * pResult = NULL; try { /*getting what to assign*/ e.getLeft().accept(*this); if (isSingleResult() == false) { clearResult(); std::wostringstream os; os << _W("Incompatible output argument.\n"); //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl; throw ast::InternalError(os.str(), 999, e.getRight().getLocation()); } pITL = getResult(); /*getting what to assign*/ e.getRight().accept(*this); if (isSingleResult() == false) { clearResult(); std::wostringstream os; os << _W("Incompatible output argument.\n"); //os << ((Location)e.right_get().getLocation()).getLocationString() << std::endl; throw ast::InternalError(os.str(), 999, e.getRight().getLocation()); } pITR = getResult(); if (pITL->getType() == GenericType::ScilabImplicitList) { ImplicitList* pIL = pITL->getAs<ImplicitList>(); if (pIL->isComputable()) { pITL = pIL->extractFullMatrix(); pIL->killMe(); } } if (pITR->getType() == GenericType::ScilabImplicitList) { ImplicitList* pIR = pITR->getAs<ImplicitList>(); if (pIR->isComputable()) { pITR = pIR->extractFullMatrix(); pIR->killMe(); } } switch (e.getOper()) { case OpExp::plus : { pResult = GenericPlus(pITL, pITR); break; } case OpExp::unaryMinus : { pResult = GenericUnaryMinus(pITR); break; } case OpExp::minus : { pResult = GenericMinus(pITL, pITR); break; } case OpExp::times: { pResult = GenericTimes(pITL, pITR); break; } case OpExp::ldivide: { pResult = GenericLDivide(pITL, pITR); break; } case OpExp::dotldivide : { pResult = GenericDotLDivide(pITL, pITR); break; } case OpExp::rdivide: { pResult = GenericRDivide(pITL, pITR); break; } case OpExp::dotrdivide : { pResult = GenericDotRDivide(pITL, pITR); break; } case OpExp::dottimes : { pResult = GenericDotTimes(pITL, pITR); break; } case OpExp::dotpower : { pResult = GenericDotPower(pITL, pITR); break; } case OpExp::eq : { pResult = GenericComparisonEqual(pITL, pITR); break; } case OpExp::ne : { pResult = GenericComparisonNonEqual(pITL, pITR); break; } case OpExp::lt : { pResult = GenericLess(pITL, pITR); break; } case OpExp::le : { pResult = GenericLessEqual(pITL, pITR); break; } case OpExp::gt : { pResult = GenericGreater(pITL, pITR); break; } case OpExp::ge : { pResult = GenericGreaterEqual(pITL, pITR); break; } case OpExp::power : { pResult = GenericPower(pITL, pITR); break; } case OpExp::krontimes : { pResult = GenericKrontimes(pITL, pITR); break; } case OpExp::kronrdivide : { pResult = GenericKronrdivide(pITL, pITR); break; } case OpExp::kronldivide : { pResult = GenericKronldivide(pITL, pITR); break; } default : break; } //overloading if (pResult == NULL) { // We did not have any algorithm matching, so we try to call OverLoad pResult = callOverloadOpExp(e.getOper(), pITL, pITR); } setResult(pResult); //clear left and/or right operands if (pResult != pITL) { pITL->killMe(); } if (pResult != pITR) { pITR->killMe(); } } catch (ast::InternalError& error) { setResult(NULL); if (pResult) { pResult->killMe(); } if (pITL && (pITL != pResult)) { pITL->killMe(); } if (pITR && (pITR != pResult)) { pITR->killMe(); } error.SetErrorLocation(e.getLocation()); throw error; } /*if (e.getDecorator().res.isConstant()) { }*/ }