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 //for Visual Leak Detector in debug compilation mode
18 #if defined(DEBUG_VLD) && defined(_DEBUG)
24 #include "execvisitor.hxx"
25 #include "stepvisitor.hxx"
26 #include "timedvisitor.hxx"
27 #include "shortcutvisitor.hxx"
28 #include "printvisitor.hxx"
29 //#include "AnalysisVisitor.hxx"
30 #include "debuggervisitor.hxx"
31 #include "debugmanager.hxx"
33 #include "visitor_common.hxx"
35 #include "context.hxx"
36 #include "generic_operations.hxx"
37 #include "types_or.hxx"
38 #include "types_and.hxx"
39 #include "localization.hxx"
41 #include "macrofile.hxx"
44 #include "listinsert.hxx"
45 #include "filemanager_interface.h"
48 #include "threadmanagement.hxx"
50 #include "coverage_instance.hxx"
55 #include "os_string.h"
56 #include "elem_common.h"
57 #include "storeCommand.h"
59 #include "scilabRead.h"
65 void RunVisitorT<T>::visitprivate(const StringExp & e)
67 CoverageInstance::invokeAndStartChrono((void*)&e);
68 if (e.getConstant() == nullptr)
70 types::String *psz = new types::String(e.getValue().c_str());
71 (const_cast<StringExp *>(&e))->setConstant(psz);
73 setResult(e.getConstant());
74 CoverageInstance::stopChrono((void*)&e);
78 void RunVisitorT<T>::visitprivate(const DoubleExp & e)
80 CoverageInstance::invokeAndStartChrono((void*)&e);
81 if (e.getConstant() == nullptr)
83 types::Double *pdbl = new types::Double(e.getValue());
84 (const_cast<DoubleExp *>(&e))->setConstant(pdbl);
86 setResult(e.getConstant());
87 CoverageInstance::stopChrono((void*)&e);
91 void RunVisitorT<T>::visitprivate(const BoolExp & e)
93 CoverageInstance::invokeAndStartChrono((void*)&e);
94 if (e.getConstant() == nullptr)
96 types::Bool *pB = new types::Bool(e.getValue());
97 (const_cast<BoolExp *>(&e))->setConstant(pB);
99 setResult(e.getConstant());
100 CoverageInstance::stopChrono((void*)&e);
104 void RunVisitorT<T>::visitprivate(const NilExp & e)
106 CoverageInstance::invokeAndStartChrono((void*)&e);
107 setResult(new types::Void());
108 CoverageInstance::stopChrono((void*)&e);
112 void RunVisitorT<T>::visitprivate(const SimpleVar & e)
114 CoverageInstance::invokeAndStartChrono((void*)&e);
115 symbol::Context* ctx = symbol::Context::getInstance();
116 symbol::Variable* var = ((SimpleVar&)e).getStack();
117 types::InternalType *pI = ctx->get(var);
121 if (e.isVerbose() && pI->isCallable() == false && ConfigVariable::isPrintOutput())
123 std::wostringstream ostr;
124 ostr << L" " << e.getSymbol().getName() << L" = ";
126 ostr << L"(" << pI->getRef() << L")";
129 if (ConfigVariable::isPrintCompact() == false)
133 scilabWriteW(ostr.str().c_str());
134 std::wostringstream ostrName;
135 ostrName << e.getSymbol().getName();
136 VariableToString(pI, ostrName.str().c_str());
139 //check if var is recalled in current scope like
144 if (e.getParent()->isSeqExp())
146 if (ctx->getScopeLevel() > 1 && var->empty() == false && var->top()->m_iLevel != ctx->getScopeLevel())
148 //put var in current scope
158 char* strErr = wide_string_to_UTF8(e.getSymbol().getName().c_str());
160 os_sprintf(pstError, _("Undefined variable: %s\n"), strErr);
161 pwstError = to_wide_string(pstError);
163 std::wstring wstError(pwstError);
165 CoverageInstance::stopChrono((void*)&e);
166 throw InternalError(wstError, 999, e.getLocation());
167 //Err, SimpleVar doesn't exist in Scilab scopes.
169 CoverageInstance::stopChrono((void*)&e);
173 void RunVisitorT<T>::visitprivate(const ColonVar & e)
175 CoverageInstance::invokeAndStartChrono((void*)&e);
176 types::Colon *pC = new types::Colon();
178 CoverageInstance::stopChrono((void*)&e);
182 void RunVisitorT<T>::visitprivate(const DollarVar & e)
184 CoverageInstance::invokeAndStartChrono((void*)&e);
185 setResult(types::Polynom::Dollar());
186 CoverageInstance::stopChrono((void*)&e);
190 void RunVisitorT<T>::visitprivate(const BreakExp & e)
192 CoverageInstance::invokeAndStartChrono((void*)&e);
193 const_cast<BreakExp*>(&e)->setBreak();
194 CoverageInstance::stopChrono((void*)&e);
198 void RunVisitorT<T>::visitprivate(const ContinueExp &e)
200 CoverageInstance::invokeAndStartChrono((void*)&e);
201 const_cast<ContinueExp*>(&e)->setContinue();
202 CoverageInstance::stopChrono((void*)&e);
206 void RunVisitorT<T>::visitprivate(const ArrayListExp & e)
208 CoverageInstance::invokeAndStartChrono((void*)&e);
209 exps_t::const_iterator it;
210 int iNbExpSize = this->getExpectedSize();
211 this->setExpectedSize(1);
213 types::typed_list lstIT;
214 for (it = e.getExps().begin(); it != e.getExps().end(); it++)
216 (*it)->accept(*this);
217 for (int j = 0; j < getResultSize(); j++)
219 lstIT.push_back(getResult(j));
225 this->setExpectedSize(iNbExpSize);
226 CoverageInstance::stopChrono((void*)&e);
230 void RunVisitorT<T>::visitprivate(const VarDec & e)
232 CoverageInstance::invokeAndStartChrono((void*)&e);
235 /*getting what to assign*/
236 e.getInit().accept(*this);
237 getResult()->IncreaseRef();
239 catch (const InternalError& error)
241 CoverageInstance::stopChrono((void*)&e);
244 CoverageInstance::stopChrono((void*)&e);
248 void RunVisitorT<T>::visitprivate(const CellExp & e)
250 CoverageInstance::invokeAndStartChrono((void*)&e);
252 exps_t::const_iterator row;
253 exps_t::const_iterator col;
256 exps_t lines = e.getLines();
258 for (row = lines.begin(); row != lines.end(); ++row)
260 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
263 iColMax = static_cast<int>(cols.size());
266 if (iColMax != static_cast<int>(cols.size()))
268 std::wostringstream os;
269 os << _W("inconsistent row/column dimensions\n");
270 //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
271 CoverageInstance::stopChrono((void*)&e);
272 throw InternalError(os.str(), 999, (*row)->getLocation());
277 types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
282 //insert items in cell
283 for (i = 0, row = lines.begin(); row != lines.end(); ++row, ++i)
285 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
286 for (j = 0, col = cols.begin(); col != cols.end(); ++col, ++j)
290 (*col)->accept(*this);
292 catch (ScilabException &)
294 CoverageInstance::stopChrono((void*)&e);
297 types::InternalType *pIT = getResult();
298 if (pIT->isImplicitList())
300 types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
315 CoverageInstance::stopChrono((void*)&e);
319 void RunVisitorT<T>::visitprivate(const FieldExp &e)
325 CoverageInstance::invokeAndStartChrono((void*)&e);
327 if (!e.getTail()->isSimpleVar())
329 wchar_t szError[bsiz];
330 os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
331 CoverageInstance::stopChrono((void*)&e);
332 throw InternalError(szError, 999, e.getLocation());
337 e.getHead()->accept(*this);
339 catch (const InternalError& error)
341 CoverageInstance::stopChrono((void*)&e);
345 if (getResult() == NULL)
347 wchar_t szError[bsiz];
348 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
349 CoverageInstance::stopChrono((void*)&e);
350 throw InternalError(szError, 999, e.getLocation());
353 // TODO: handle case where getSize() > 1
354 // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
356 if (getResultSize() > 1)
359 wchar_t szError[bsiz];
360 os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
361 CoverageInstance::stopChrono((void*)&e);
362 throw InternalError(szError, 999, e.getLocation());
365 SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
366 std::wstring wstField = psvRightMember->getSymbol().getName();
367 types::InternalType * pValue = getResult();
368 types::InternalType * pReturn = NULL;
373 if (pValue->isGenericType() || pValue->isUserType())
375 ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
378 catch (std::wstring & err)
380 CoverageInstance::stopChrono((void*)&e);
381 throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
388 std::wostringstream os;
389 os << _W("Invalid index.\n");
390 CoverageInstance::stopChrono((void*)&e);
391 throw InternalError(os.str(), 999, e.getLocation());
395 if (pValue->isDeletable())
397 if (pValue->isContainer())
399 // prevent delete of pReturn in case where
400 // extract not return a clone
401 pReturn->IncreaseRef();
403 pReturn->DecreaseRef();
411 else if (pValue->isFieldExtractionOverloadable())
413 types::typed_list in;
414 types::typed_list out;
416 types::String* pS = new types::String(wstField.c_str());
418 //TODO: in the case where overload is a macro there is no need to incref in
419 // because args will be put in context, removed and killed if required.
420 // But if the overload is a function... it is another story...
423 pValue->IncreaseRef();
426 in.push_back(pValue);
427 types::Callable::ReturnValue Ret = types::Callable::Error;
428 std::wstring stType = pValue->getShortTypeStr();
432 Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, true);
434 catch (const InternalError& ie)
438 //to compatibility with scilab 5 code.
439 //tlist/mlist name are truncated to 8 first character
440 if (stType.size() > 8)
442 Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, true);
446 CoverageInstance::stopChrono((void*)&e);
450 catch (const InternalError& ie)
453 if (pValue->isList())
455 Ret = Overload::call(L"%l_e", in, 1, out, true);
459 CoverageInstance::stopChrono((void*)&e);
465 if (Ret != types::Callable::OK)
469 CoverageInstance::stopChrono((void*)&e);
470 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
479 wchar_t szError[bsiz];
480 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
481 CoverageInstance::stopChrono((void*)&e);
482 throw InternalError(szError, 999, e.getLocation());
485 CoverageInstance::stopChrono((void*)&e);
489 void RunVisitorT<T>::visitprivate(const IfExp &e)
491 CoverageInstance::invokeAndStartChrono((void*)&e);
493 //Create local exec visitor
494 ShortCutVisitor SCTest;
495 bool bTestStatus = false;
500 e.getTest().accept(SCTest);
501 e.getTest().accept(*this);
503 catch (ScilabException &)
505 CoverageInstance::stopChrono((void*)&e);
509 bTestStatus = getResult()->isTrue();
513 if (bTestStatus == true)
515 e.getThen().accept(*this);
517 else if (e.hasElse())
519 e.getElse().accept(*this);
522 catch (ScilabException &)
524 CoverageInstance::stopChrono((void*)&e);
528 bool elseIsBreak = e.hasElse() && (&e.getElse())->isBreak();
529 if (e.isBreakable() && (elseIsBreak || (&e.getThen())->isBreak()))
531 const_cast<IfExp*>(&e)->setBreak();
532 const_cast<Exp*>(&e.getThen())->resetBreak();
535 const_cast<Exp*>(&e.getElse())->resetBreak();
539 bool elseIsContinue = e.hasElse() && (&e.getElse())->isContinue();
540 if (e.isContinuable() && (elseIsContinue || (&e.getThen())->isContinue()))
542 const_cast<IfExp*>(&e)->setContinue();
543 const_cast<Exp*>(&e.getThen())->resetContinue();
546 const_cast<Exp*>(&e.getElse())->resetContinue();
550 bool elseIsReturn = e.hasElse() && (&e.getElse())->isReturn();
551 if (e.isReturnable() && (elseIsReturn || (&e.getThen())->isReturn()))
553 const_cast<IfExp*>(&e)->setReturn();
554 const_cast<Exp*>(&e.getThen())->resetReturn();
557 const_cast<Exp*>(&e.getElse())->resetReturn();
561 CoverageInstance::stopChrono((void*)&e);
565 void RunVisitorT<T>::visitprivate(const WhileExp &e)
567 CoverageInstance::invokeAndStartChrono((void*)&e);
569 //Create local exec visitor
570 ShortCutVisitor SCTest;
574 //manage & and | like && and ||
575 e.getTest().accept(SCTest);
577 e.getTest().accept(*this);
579 catch (ScilabException &)
581 CoverageInstance::stopChrono((void*)&e);
585 types::InternalType* pIT = getResult();
587 while (pIT->isTrue())
594 e.getBody().accept(*this);
596 catch (ScilabException &)
598 CoverageInstance::stopChrono((void*)&e);
602 //clear old result value before evaluate new one
603 if (getResult() != NULL)
605 getResult()->killMe();
608 if (e.getBody().isBreak())
610 const_cast<Exp*>(&(e.getBody()))->resetBreak();
614 if (e.getBody().isReturn())
616 const_cast<WhileExp*>(&e)->setReturn();
617 const_cast<Exp*>(&(e.getBody()))->resetReturn();
621 if (e.getBody().isContinue())
623 const_cast<Exp*>(&(e.getBody()))->resetContinue();
628 e.getTest().accept(*this);
630 catch (ScilabException &)
632 CoverageInstance::stopChrono((void*)&e);
639 //clear result of condition or result of body
641 CoverageInstance::stopChrono((void*)&e);
645 void RunVisitorT<T>::visitprivate(const ForExp &e)
647 CoverageInstance::invokeAndStartChrono((void*)&e);
648 symbol::Context* ctx = symbol::Context::getInstance();
649 //vardec visit increase its result reference
652 e.getVardec().accept(*this);
654 catch (ScilabException &)
656 CoverageInstance::stopChrono((void*)&e);
659 types::InternalType* pIT = getResult();
661 if (pIT->isImplicitList())
664 types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
665 //get IL initial Type
666 types::InternalType * pIL = pVar->getInitalType();
667 //std::cout << "for IL: " << pIL << std::endl;
668 //std::cout << " for IV: " << pIT << std::endl;
670 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
672 if (ctx->isprotected(var))
674 std::wostringstream os;
675 os << _W("Redefining permanent variable.\n");
676 CoverageInstance::stopChrono((void*)&e);
677 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
681 //use ref count to lock var against clear and detect any changes
684 int size = static_cast<int>(pVar->getSize());
685 for (int i = 0; i < size; ++i)
687 //check if loop index has changed, deleted, copy ...
688 if (pIL->getRef() != 2)
690 switch (pIL->getRef())
697 //someone assign me to another var
702 //no need to destroy, it already assign to another var
706 pIL = pVar->getInitalType();
709 //update me ( must decrease ref of a )
710 if (ctx->isprotected(var))
712 std::wostringstream os;
713 os << _W("Redefining permanent variable.\n");
714 CoverageInstance::stopChrono((void*)&e);
715 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
723 pVar->extractValue(i, pIL);
727 e.getBody().accept(*this);
729 catch (const InternalError& ie)
731 //unlock loop index and implicit list
738 CoverageInstance::stopChrono((void*)&e);
742 if (e.getBody().isBreak())
744 const_cast<Exp&>(e.getBody()).resetBreak();
748 if (e.getBody().isContinue())
750 const_cast<Exp&>(e.getBody()).resetContinue();
754 if (e.getBody().isReturn())
756 const_cast<ForExp&>(e).setReturn();
757 const_cast<Exp&>(e.getBody()).resetReturn();
766 else if (pIT->isList())
768 types::List* pL = pIT->getAs<types::List>();
769 const int size = pL->getSize();
770 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
771 for (int i = 0; i < size; ++i)
773 types::InternalType* pNew = pL->get(i);
775 if (ctx->isprotected(var))
777 std::wostringstream os;
778 os << _W("Redefining permanent variable.\n");
779 CoverageInstance::stopChrono((void*)&e);
780 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
786 e.getBody().accept(*this);
788 catch (const InternalError& ie)
794 CoverageInstance::stopChrono((void*)&e);
798 if (e.getBody().isBreak())
800 const_cast<Exp*>(&(e.getBody()))->resetBreak();
804 if (e.getBody().isContinue())
806 const_cast<Exp*>(&(e.getBody()))->resetContinue();
810 if (e.getBody().isReturn())
812 const_cast<ForExp*>(&e)->setReturn();
813 const_cast<Exp&>(e.getBody()).resetReturn();
818 else if (pIT->isGenericType())
820 //Matrix i = [1,3,2,6] or other type
821 types::GenericType* pVar = pIT->getAs<types::GenericType>();
822 if (pVar->getDims() > 2)
826 CoverageInstance::stopChrono((void*)&e);
827 throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
830 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
831 for (int i = 0; i < pVar->getCols(); i++)
833 types::GenericType* pNew = pVar->getColumnValues(i);
838 CoverageInstance::stopChrono((void*)&e);
839 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
842 if (ctx->isprotected(var))
844 std::wostringstream os;
845 os << _W("Redefining permanent variable.\n");
846 CoverageInstance::stopChrono((void*)&e);
847 throw InternalError(os.str(), 999, e.getVardec().getLocation());
853 e.getBody().accept(*this);
855 catch (const InternalError& ie)
861 CoverageInstance::stopChrono((void*)&e);
865 if (e.getBody().isBreak())
867 const_cast<Exp*>(&(e.getBody()))->resetBreak();
871 if (e.getBody().isContinue())
873 const_cast<Exp*>(&(e.getBody()))->resetContinue();
877 if (e.getBody().isReturn())
879 const_cast<ForExp*>(&e)->setReturn();
880 const_cast<Exp&>(e.getBody()).resetReturn();
889 CoverageInstance::stopChrono((void*)&e);
890 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
897 CoverageInstance::stopChrono((void*)&e);
901 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
903 CoverageInstance::invokeAndStartChrono((void*)&e);
906 if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
909 ConfigVariable::DecreasePauseLevel();
910 ConfigVariable::macroFirstLine_end();
911 CoverageInstance::stopChrono((void*)&e);
916 const_cast<ReturnExp*>(&e)->setReturn();
923 if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
925 CoverageInstance::stopChrono((void*)&e);
926 throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
928 //in case of CallExp, we can return only one value
929 int iSaveExpectedSize = getExpectedSize();
933 e.getExp().accept(*this);
935 catch (ScilabException &)
937 CoverageInstance::stopChrono((void*)&e);
940 setExpectedSize(iSaveExpectedSize);
941 const_cast<ReturnExp*>(&e)->setReturn();
944 CoverageInstance::stopChrono((void*)&e);
948 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
950 CoverageInstance::invokeAndStartChrono((void*)&e);
952 //e.getSelect()->accept(*this);
953 //InternalType* pIT = getResult();
954 //setResult(nullptr);
955 //if (pIT && pIT->isDouble())
957 // Double * pDbl = static_cast<Double *>(pIT);
958 // if (!pDbl->isComplex() && pDbl->getSize() == 1)
961 // if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
963 // Exp * exp = e.getExp(val);
967 // Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
968 // if (e.isBreakable())
970 // const_cast<IntSelectExp*>(&e)->resetBreak();
971 // body->setBreakable();
974 // if (e.isContinuable())
976 // const_cast<IntSelectExp*>(&e)->resetContinue();
977 // body->setContinuable();
980 // if (e.isReturnable())
982 // const_cast<IntSelectExp*>(&e)->resetReturn();
983 // body->setReturnable();
989 // body->accept(*this);
991 // catch (const InternalError& ie)
997 // if (e.isBreakable() && body->isBreak())
999 // const_cast<IntSelectExp*>(&e)->setBreak();
1000 // body->resetBreak();
1003 // if (e.isContinuable() && body->isContinue())
1005 // const_cast<IntSelectExp*>(&e)->setContinue();
1006 // body->resetContinue();
1009 // if (e.isReturnable() && body->isReturn())
1011 // const_cast<IntSelectExp*>(&e)->setReturn();
1012 // body->resetReturn();
1023 e.getOriginal()->accept(*this);
1025 catch (ScilabException &)
1027 CoverageInstance::stopChrono((void*)&e);
1031 CoverageInstance::stopChrono((void*)&e);
1035 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
1037 CoverageInstance::invokeAndStartChrono((void*)&e);
1040 e.getSelect()->accept(*this);
1042 catch (ScilabException &)
1044 CoverageInstance::stopChrono((void*)&e);
1047 types::InternalType* pIT = getResult();
1050 if (pIT && pIT->isString())
1052 types::String * pStr = static_cast<types::String *>(pIT);
1053 if (pStr->getSize() == 1)
1055 if (wchar_t * s = pStr->get(0))
1057 const std::wstring ws(s);
1058 Exp * exp = e.getExp(ws);
1062 Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
1063 if (e.isBreakable())
1065 const_cast<StringSelectExp*>(&e)->resetBreak();
1066 body->setBreakable();
1069 if (e.isContinuable())
1071 const_cast<StringSelectExp*>(&e)->resetContinue();
1072 body->setContinuable();
1075 if (e.isReturnable())
1077 const_cast<StringSelectExp*>(&e)->resetReturn();
1078 body->setReturnable();
1084 body->accept(*this);
1086 catch (const InternalError& ie)
1089 CoverageInstance::stopChrono((void*)&e);
1093 if (e.isBreakable() && body->isBreak())
1095 const_cast<StringSelectExp*>(&e)->setBreak();
1099 if (e.isContinuable() && body->isContinue())
1101 const_cast<StringSelectExp*>(&e)->setContinue();
1102 body->resetContinue();
1105 if (e.isReturnable() && body->isReturn())
1107 const_cast<StringSelectExp*>(&e)->setReturn();
1108 body->resetReturn();
1119 e.getOriginal()->accept(*this);
1121 catch (ScilabException &)
1123 CoverageInstance::stopChrono((void*)&e);
1127 CoverageInstance::stopChrono((void*)&e);
1131 void RunVisitorT<T>::visitprivate(const SelectExp &e)
1133 // FIXME : exec select ... case ... else ... end
1134 CoverageInstance::invokeAndStartChrono((void*)&e);
1137 e.getSelect()->accept(*this);
1139 catch (ScilabException &)
1141 CoverageInstance::stopChrono((void*)&e);
1147 types::InternalType* pIT = getResult();
1151 // protect pIT to avoid double free when
1152 // the variable in select is override in the case
1156 exps_t cases = e.getCases();
1157 for (auto exp : cases)
1159 CaseExp * pCase = exp->getAs<CaseExp>();
1162 pCase->getTest()->accept(*this);
1164 catch (ScilabException &)
1166 CoverageInstance::stopChrono((void*)&e);
1169 types::InternalType *pITCase = getResult();
1173 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
1177 else if (*pITCase == *pIT)
1182 pCase->getBody()->accept(*this);
1184 catch (const InternalError& ie)
1188 CoverageInstance::stopChrono((void*)&e);
1192 if (e.isBreakable() && pCase->getBody()->isBreak())
1194 const_cast<SelectExp*>(&e)->setBreak();
1195 pCase->getBody()->resetBreak();
1198 if (e.isContinuable() && pCase->getBody()->isContinue())
1200 const_cast<SelectExp*>(&e)->setContinue();
1201 pCase->getBody()->resetContinue();
1204 if (e.isReturnable() && pCase->getBody()->isReturn())
1206 const_cast<SelectExp*>(&e)->setReturn();
1207 pCase->getBody()->resetReturn();
1220 if (bCase == false && e.getDefaultCase() != NULL)
1225 e.getDefaultCase()->accept(*this);
1227 catch (const InternalError& ie)
1234 CoverageInstance::stopChrono((void*)&e);
1238 if (e.isBreakable() && e.getDefaultCase()->isBreak())
1240 const_cast<SelectExp*>(&e)->setBreak();
1241 e.getDefaultCase()->resetBreak();
1244 if (e.isContinuable() && e.getDefaultCase()->isContinue())
1246 const_cast<SelectExp*>(&e)->setContinue();
1247 e.getDefaultCase()->resetContinue();
1250 if (e.isReturnable() && e.getDefaultCase()->isReturn())
1252 const_cast<SelectExp*>(&e)->setReturn();
1253 e.getDefaultCase()->resetReturn();
1264 CoverageInstance::stopChrono((void*)&e);
1268 void RunVisitorT<T>::visitprivate(const NotExp &e)
1270 CoverageInstance::invokeAndStartChrono((void*)&e);
1276 e.getExp().accept(*this);
1278 catch (ScilabException &)
1280 CoverageInstance::stopChrono((void*)&e);
1284 types::InternalType * pValue = getResult();
1285 types::InternalType * pReturn = NULL;
1286 if (pValue->neg(pReturn))
1288 if (pValue != pReturn)
1297 // neg returned false so the negation is not possible so we call the overload (%foo_5)
1298 types::typed_list in;
1299 types::typed_list out;
1301 pValue->IncreaseRef();
1302 in.push_back(pValue);
1304 types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, true);
1306 if (Ret != types::Callable::OK)
1308 cleanInOut(in, out);
1309 CoverageInstance::stopChrono((void*)&e);
1310 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1316 CoverageInstance::stopChrono((void*)&e);
1320 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1322 CoverageInstance::invokeAndStartChrono((void*)&e);
1325 e.getExp().accept(*this);
1327 catch (ScilabException &)
1329 CoverageInstance::stopChrono((void*)&e);
1333 if (getResultSize() != 1)
1336 wchar_t szError[bsiz];
1337 os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1338 CoverageInstance::stopChrono((void*)&e);
1339 throw InternalError(szError, 999, e.getLocation());
1342 types::InternalType * pValue = getResult();
1343 types::InternalType * pReturn = NULL;
1344 const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1346 if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1348 if (pValue != pReturn)
1354 CoverageInstance::stopChrono((void*)&e);
1360 // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1361 types::typed_list in;
1362 types::typed_list out;
1364 pValue->IncreaseRef();
1365 in.push_back(pValue);
1367 types::Callable::ReturnValue Ret;
1370 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, true);
1374 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, true);
1377 if (Ret != types::Callable::OK)
1379 cleanInOut(in, out);
1380 CoverageInstance::stopChrono((void*)&e);
1381 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1388 CoverageInstance::stopChrono((void*)&e);
1392 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1394 CoverageInstance::invokeAndStartChrono((void*)&e);
1395 symbol::Context* ctx = symbol::Context::getInstance();
1401 // funcprot(0) : do nothing
1402 // funcprot(1) && warning(on) : warning
1403 //get input parameters list
1404 std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1405 const exps_t & vars = e.getArgs().getVars();
1406 for (const auto var : vars)
1408 pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1411 //get output parameters list
1412 std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1413 const exps_t & rets = e.getReturns().getVars();
1414 for (const auto ret : rets)
1416 pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1419 types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1420 const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1421 pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1424 pMacro->setFileName(e.getMacro()->getFileName());
1427 if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1430 std::wostringstream os;
1431 os << _W("Redefining permanent variable.\n");
1432 CoverageInstance::stopChrono((void*)&e);
1433 throw InternalError(os.str(), 999, e.getLocation());
1436 if (ctx->addMacro(pMacro) == false)
1438 char pstError[1024];
1439 char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1440 os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1441 wchar_t* pwstError = to_wide_string(pstError);
1442 std::wstring wstError(pwstError);
1446 CoverageInstance::stopChrono((void*)&e);
1447 throw InternalError(wstError, 999, e.getLocation());
1450 CoverageInstance::stopChrono((void*)&e);
1454 void RunVisitorT<T>::visitprivate(const ListExp &e)
1456 CoverageInstance::invokeAndStartChrono((void*)&e);
1459 e.getStart().accept(*this);
1461 catch (ScilabException &)
1463 CoverageInstance::stopChrono((void*)&e);
1467 types::InternalType* pITStart = getResult();
1468 types::GenericType* pStart = static_cast<types::GenericType*>(pITStart);
1469 if (pITStart == NULL ||
1470 ((pITStart->isGenericType() == false || pStart->getSize() != 1 || (pStart->isDouble() && pStart->getAs<types::Double>()->isComplex())) &&
1471 pStart->isList() == false)) // list case => call overload
1474 wchar_t szError[bsiz];
1475 if (pITStart && pITStart->isImplicitList())
1477 os_swprintf(szError, bsiz, _W("%ls: Too many %ls or wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", L"':'", 1);
1481 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1489 CoverageInstance::stopChrono((void*)&e);
1490 throw InternalError(szError, 999, e.getLocation());
1495 e.getStep().accept(*this);
1497 catch (ScilabException &)
1499 CoverageInstance::stopChrono((void*)&e);
1503 types::InternalType* pITStep = getResult();
1504 types::GenericType* pStep = static_cast<types::GenericType*>(pITStep);
1506 if (pITStep == NULL ||
1507 ((pITStep->isGenericType() == false || pStep->getSize() != 1 || (pStep->isDouble() && pStep->getAs<types::Double>()->isComplex())) &&
1508 pStep->isList() == false)) // list case => call overload
1517 wchar_t szError[bsiz];
1518 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1519 CoverageInstance::stopChrono((void*)&e);
1520 throw InternalError(szError, 999, e.getLocation());
1525 e.getEnd().accept(*this);
1527 catch (ScilabException &)
1529 CoverageInstance::stopChrono((void*)&e);
1533 types::InternalType* pITEnd = getResult();
1534 types::GenericType* pEnd = static_cast<types::GenericType*>(pITEnd);
1536 if (pITEnd == NULL ||
1537 ((pITEnd->isGenericType() == false || pEnd->getSize() != 1 || (pEnd->isDouble() && pEnd->getAs<types::Double>()->isComplex())) &&
1538 pEnd->isList() == false)) // list case => call overload
1548 wchar_t szError[bsiz];
1549 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2 + e.hasExplicitStep());
1550 CoverageInstance::stopChrono((void*)&e);
1551 throw InternalError(szError, 999, e.getLocation());
1554 ////check if implicitlist is 1:$ to replace by ':'
1555 //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1557 // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1559 // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1560 // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1562 // setResult(new Colon());
1568 //check compatibility
1569 // double : double : double or poly : poly : poly and mix like double : double : poly
1570 if ((pStart->isPoly() || pStart->isDouble()) &&
1571 (pStep->isPoly() || pStep->isDouble()) &&
1572 (pEnd->isPoly() || pEnd->isDouble()))
1574 // No need to kill piStart, ... because Implicit list ctor will incref them
1575 setResult(new types::ImplicitList(pStart, pStep, pEnd));
1576 CoverageInstance::stopChrono((void*)&e);
1580 // int : double or int : int
1581 if (pStart->isInt() &&
1582 (pStep->isDouble() || pStep->isInt()) &&
1585 // check for same int type int8, int 16 ...
1586 if (pStart->getType() == pEnd->getType() &&
1587 (pStart->getType() == pStep->getType() ||
1590 // No need to kill piStart, ... because Implicit list ctor will incref them
1591 setResult(new types::ImplicitList(pStart, pStep, pEnd));
1592 CoverageInstance::stopChrono((void*)&e);
1598 types::Callable::ReturnValue Ret;
1599 types::typed_list in;
1600 types::typed_list out;
1602 pStart->IncreaseRef();
1603 in.push_back(pStart);
1607 if (e.hasExplicitStep())
1610 //call overload %typeStart_b_typeStep
1611 pStep->IncreaseRef();
1612 in.push_back(pStep);
1613 pEnd->IncreaseRef();
1615 Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pStep->getShortTypeStr(), in, 1, out, true);
1620 //call overload %typeStart_b_typeEnd
1622 pEnd->IncreaseRef();
1624 Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pEnd->getShortTypeStr(), in, 1, out, true);
1627 catch (const InternalError& error)
1630 cleanInOut(in, out);
1631 CoverageInstance::stopChrono((void*)&e);
1635 if (Ret != types::Callable::OK)
1638 cleanInOut(in, out);
1639 CoverageInstance::stopChrono((void*)&e);
1640 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1645 CoverageInstance::stopChrono((void*)&e);
1649 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1654 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1656 CoverageInstance::invokeAndStartChrono((void*)&e);
1659 e.getOriginal()->accept(*this);
1661 catch (ScilabException &)
1663 CoverageInstance::stopChrono((void*)&e);
1669 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1671 CoverageInstance::invokeAndStartChrono((void*)&e);
1672 types::InternalType* pIT = NULL;
1673 types::Double* ad = NULL;
1677 types::Double* xd = NULL;
1681 types::Double* yd = NULL;
1685 //check types and dimensions
1688 const Exp &ye = e.getY();
1693 catch (ScilabException &)
1695 CoverageInstance::stopChrono((void*)&e);
1700 if (pIT->isDouble())
1702 yd = pIT->getAs<types::Double>();
1703 if (yd->getDims() == 2 && yd->isComplex() == false)
1713 e.getOriginal()->accept(*this);
1715 catch (ScilabException &)
1717 CoverageInstance::stopChrono((void*)&e);
1720 CoverageInstance::stopChrono((void*)&e);
1729 e.getOriginal()->accept(*this);
1731 catch (ScilabException &)
1733 CoverageInstance::stopChrono((void*)&e);
1736 CoverageInstance::stopChrono((void*)&e);
1741 const Exp &xe = e.getX();
1746 catch (ScilabException &)
1748 CoverageInstance::stopChrono((void*)&e);
1753 if (pIT->isDouble())
1755 xd = pIT->getAs<types::Double>();
1756 if (xd->isScalar() && xd->isComplex() == false)
1763 else if (xd->getDims() == 2 && xd->isComplex() == false)
1774 e.getOriginal()->accept(*this);
1776 catch (ScilabException &)
1778 CoverageInstance::stopChrono((void*)&e);
1781 CoverageInstance::stopChrono((void*)&e);
1791 e.getOriginal()->accept(*this);
1793 catch (ScilabException &)
1795 CoverageInstance::stopChrono((void*)&e);
1798 CoverageInstance::stopChrono((void*)&e);
1802 const Exp &ae = e.getA();
1807 catch (ScilabException &)
1809 CoverageInstance::stopChrono((void*)&e);
1814 if (pIT->isDouble())
1818 xd = pIT->getAs<types::Double>();
1819 //X is scalar it become A
1821 if (xd->getDims() == 2 && xd->isComplex() == false)
1833 e.getOriginal()->accept(*this);
1835 catch (ScilabException &)
1837 CoverageInstance::stopChrono((void*)&e);
1840 CoverageInstance::stopChrono((void*)&e);
1846 //a is a and it must be scalar
1847 ad = pIT->getAs<types::Double>();
1848 if (/*ad->isScalar() && */ad->isComplex() == false)
1850 ar = ad->getRows(); //1;
1851 ac = ad->getCols();//1;
1860 e.getOriginal()->accept(*this);
1862 catch (ScilabException &)
1864 CoverageInstance::stopChrono((void*)&e);
1879 e.getOriginal()->accept(*this);
1881 catch (ScilabException &)
1883 CoverageInstance::stopChrono((void*)&e);
1886 CoverageInstance::stopChrono((void*)&e);
1890 // If we get here we are certain that ad, xd & yd have been set
1899 //Double* od = (Double*)yd->clone();
1900 C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1905 CoverageInstance::stopChrono((void*)&e);
1908 else if (ac == xr && ar == yr && xc == yc)
1912 C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1915 CoverageInstance::stopChrono((void*)&e);
1925 e.getOriginal()->accept(*this);
1927 catch (ScilabException &)
1929 CoverageInstance::stopChrono((void*)&e);
1932 CoverageInstance::stopChrono((void*)&e);
1938 void RunVisitorT<T>::visitprivate(const TryCatchExp &e)
1940 CoverageInstance::invokeAndStartChrono((void*)&e);
1941 //save current prompt mode
1942 bool oldVal = ConfigVariable::isSilentError();
1943 int oldMode = ConfigVariable::getPromptMode();
1944 //set mode silent for errors
1945 ConfigVariable::setSilentError(true);
1947 symbol::Context* pCtx = symbol::Context::getInstance();
1950 int scope = pCtx->getScopeLevel();
1951 int level = ConfigVariable::getRecursionLevel();
1954 const_cast<Exp*>(&e.getTry())->setReturnable();
1955 e.getTry().accept(*this);
1956 //restore previous prompt mode
1957 ConfigVariable::setSilentError(oldVal);
1959 if (e.getTry().isReturn())
1961 const_cast<Exp*>(&e.getTry())->resetReturn();
1962 const_cast<TryCatchExp*>(&e)->setReturn();
1965 catch (const RecursionException& /* re */)
1967 ConfigVariable::setPromptMode(oldMode);
1969 //close opened scope during try
1970 while (pCtx->getScopeLevel() > scope)
1975 //decrease recursion to init value and close where
1976 while (ConfigVariable::getRecursionLevel() > level)
1978 ConfigVariable::where_end();
1979 ConfigVariable::decreaseRecursion();
1982 //print msg about recursion limit and trigger an error
1984 os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
1985 CoverageInstance::stopChrono((void*)&e);
1986 throw ast::InternalError(sz);
1990 catch (const InternalError& /* ie */)
1992 //restore previous prompt mode
1993 ConfigVariable::setSilentError(oldVal);
1995 ConfigVariable::setLastErrorCall();
1996 // reset call stack filled when error occurred
1997 ConfigVariable::resetWhereError();
2000 const_cast<Exp*>(&e.getCatch())->setReturnable();
2001 e.getCatch().accept(*this);
2002 if (e.getCatch().isReturn())
2004 const_cast<Exp*>(&e.getCatch())->resetReturn();
2005 const_cast<TryCatchExp*>(&e)->setReturn();
2008 catch (ScilabException &)
2010 CoverageInstance::stopChrono((void*)&e);
2014 CoverageInstance::stopChrono((void*)&e);
2018 } /* namespace ast */
2020 #include "run_SeqExp.hpp"
2021 #include "run_CallExp.hpp"
2022 #include "run_MatrixExp.hpp"
2023 #include "run_OpExp.hpp"
2024 #include "run_AssignExp.hpp"
2026 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
2027 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
2028 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
2029 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;