2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - 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 //for Visual Leak Detector in debug compilation mode
15 #if defined(DEBUG_VLD) && defined(_DEBUG)
21 #include "execvisitor.hxx"
22 #include "stepvisitor.hxx"
23 #include "timedvisitor.hxx"
24 #include "shortcutvisitor.hxx"
25 #include "printvisitor.hxx"
26 //#include "AnalysisVisitor.hxx"
27 #include "debuggervisitor.hxx"
28 #include "debugmanager.hxx"
30 #include "visitor_common.hxx"
32 #include "context.hxx"
33 #include "generic_operations.hxx"
34 #include "types_or.hxx"
35 #include "types_and.hxx"
36 #include "localization.hxx"
38 #include "macrofile.hxx"
41 #include "filemanager_interface.h"
44 #include "threadmanagement.hxx"
46 #include "coverage_instance.hxx"
51 #include "os_string.h"
52 #include "elem_common.h"
53 #include "storeCommand.h"
55 #include "scilabRead.h"
61 void RunVisitorT<T>::visitprivate(const StringExp & e)
63 CoverageInstance::invokeAndStartChrono((void*)&e);
64 if (e.getConstant() == nullptr)
66 types::String *psz = new types::String(e.getValue().c_str());
67 (const_cast<StringExp *>(&e))->setConstant(psz);
69 setResult(e.getConstant());
70 CoverageInstance::stopChrono((void*)&e);
74 void RunVisitorT<T>::visitprivate(const DoubleExp & e)
76 CoverageInstance::invokeAndStartChrono((void*)&e);
77 if (e.getConstant() == nullptr)
79 types::Double *pdbl = new types::Double(e.getValue());
80 (const_cast<DoubleExp *>(&e))->setConstant(pdbl);
82 setResult(e.getConstant());
83 CoverageInstance::stopChrono((void*)&e);
87 void RunVisitorT<T>::visitprivate(const BoolExp & e)
89 CoverageInstance::invokeAndStartChrono((void*)&e);
90 if (e.getConstant() == nullptr)
92 types::Bool *pB = new types::Bool(e.getValue());
93 (const_cast<BoolExp *>(&e))->setConstant(pB);
95 setResult(e.getConstant());
96 CoverageInstance::stopChrono((void*)&e);
100 void RunVisitorT<T>::visitprivate(const NilExp & e)
102 CoverageInstance::invokeAndStartChrono((void*)&e);
103 setResult(new types::Void());
104 CoverageInstance::stopChrono((void*)&e);
108 void RunVisitorT<T>::visitprivate(const SimpleVar & e)
110 CoverageInstance::invokeAndStartChrono((void*)&e);
111 symbol::Context* ctx = symbol::Context::getInstance();
112 symbol::Variable* var = ((SimpleVar&)e).getStack();
113 types::InternalType *pI = ctx->get(var);
117 if (e.isVerbose() && pI->isCallable() == false && ConfigVariable::isPromptShow())
119 std::wostringstream ostr;
120 ostr << e.getSymbol().getName() << L" = ";
122 ostr << L"(" << pI->getRef() << L")";
126 scilabWriteW(ostr.str().c_str());
127 std::wostringstream ostrName;
128 ostrName << e.getSymbol().getName();
129 VariableToString(pI, ostrName.str().c_str());
132 //check if var is recalled in current scope like
137 if (e.getParent()->isSeqExp())
139 if (ctx->getScopeLevel() > 1 && var->empty() == false && var->top()->m_iLevel != ctx->getScopeLevel())
141 //put var in current scope
151 char* strErr = wide_string_to_UTF8(e.getSymbol().getName().c_str());
153 os_sprintf(pstError, _("Undefined variable: %s\n"), strErr);
154 pwstError = to_wide_string(pstError);
156 std::wstring wstError(pwstError);
158 CoverageInstance::stopChrono((void*)&e);
159 throw InternalError(wstError, 999, e.getLocation());
160 //Err, SimpleVar doesn't exist in Scilab scopes.
162 CoverageInstance::stopChrono((void*)&e);
166 void RunVisitorT<T>::visitprivate(const ColonVar & e)
168 CoverageInstance::invokeAndStartChrono((void*)&e);
169 types::Colon *pC = new types::Colon();
171 CoverageInstance::stopChrono((void*)&e);
175 void RunVisitorT<T>::visitprivate(const DollarVar & e)
177 CoverageInstance::invokeAndStartChrono((void*)&e);
178 setResult(types::Polynom::Dollar());
179 CoverageInstance::stopChrono((void*)&e);
183 void RunVisitorT<T>::visitprivate(const BreakExp & e)
185 CoverageInstance::invokeAndStartChrono((void*)&e);
186 const_cast<BreakExp*>(&e)->setBreak();
187 CoverageInstance::stopChrono((void*)&e);
191 void RunVisitorT<T>::visitprivate(const ContinueExp &e)
193 CoverageInstance::invokeAndStartChrono((void*)&e);
194 const_cast<ContinueExp*>(&e)->setContinue();
195 CoverageInstance::stopChrono((void*)&e);
199 void RunVisitorT<T>::visitprivate(const ArrayListExp & e)
201 CoverageInstance::invokeAndStartChrono((void*)&e);
202 exps_t::const_iterator it;
203 int iNbExpSize = this->getExpectedSize();
204 this->setExpectedSize(1);
206 types::typed_list lstIT;
207 for (it = e.getExps().begin(); it != e.getExps().end(); it++)
209 (*it)->accept(*this);
210 for (int j = 0; j < getResultSize(); j++)
212 lstIT.push_back(getResult(j));
218 this->setExpectedSize(iNbExpSize);
219 CoverageInstance::stopChrono((void*)&e);
223 void RunVisitorT<T>::visitprivate(const VarDec & e)
225 CoverageInstance::invokeAndStartChrono((void*)&e);
228 /*getting what to assign*/
229 e.getInit().accept(*this);
230 getResult()->IncreaseRef();
232 catch (const InternalError& error)
234 CoverageInstance::stopChrono((void*)&e);
237 CoverageInstance::stopChrono((void*)&e);
241 void RunVisitorT<T>::visitprivate(const CellExp & e)
243 CoverageInstance::invokeAndStartChrono((void*)&e);
245 exps_t::const_iterator row;
246 exps_t::const_iterator col;
249 exps_t lines = e.getLines();
251 for (row = lines.begin(); row != lines.end(); ++row)
253 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
256 iColMax = static_cast<int>(cols.size());
259 if (iColMax != static_cast<int>(cols.size()))
261 std::wostringstream os;
262 os << _W("inconsistent row/column dimensions\n");
263 //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
264 CoverageInstance::stopChrono((void*)&e);
265 throw InternalError(os.str(), 999, (*row)->getLocation());
270 types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
275 //insert items in cell
276 for (i = 0, row = lines.begin(); row != lines.end(); ++row, ++i)
278 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
279 for (j = 0, col = cols.begin(); col != cols.end(); ++col, ++j)
283 (*col)->accept(*this);
285 catch (ScilabException &)
287 CoverageInstance::stopChrono((void*)&e);
290 types::InternalType *pIT = getResult();
291 if (pIT->isImplicitList())
293 types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
308 CoverageInstance::stopChrono((void*)&e);
312 void RunVisitorT<T>::visitprivate(const FieldExp &e)
318 CoverageInstance::invokeAndStartChrono((void*)&e);
320 if (!e.getTail()->isSimpleVar())
322 wchar_t szError[bsiz];
323 os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
324 CoverageInstance::stopChrono((void*)&e);
325 throw InternalError(szError, 999, e.getLocation());
330 e.getHead()->accept(*this);
332 catch (const InternalError& error)
334 CoverageInstance::stopChrono((void*)&e);
338 if (getResult() == NULL)
340 wchar_t szError[bsiz];
341 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
342 CoverageInstance::stopChrono((void*)&e);
343 throw InternalError(szError, 999, e.getLocation());
346 // TODO: handle case where getSize() > 1
347 // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
349 if (getResultSize() > 1)
352 wchar_t szError[bsiz];
353 os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
354 CoverageInstance::stopChrono((void*)&e);
355 throw InternalError(szError, 999, e.getLocation());
358 SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
359 std::wstring wstField = psvRightMember->getSymbol().getName();
360 types::InternalType * pValue = getResult();
361 types::InternalType * pReturn = NULL;
366 if (pValue->isGenericType() || pValue->isUserType())
368 ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
371 catch (std::wstring & err)
373 CoverageInstance::stopChrono((void*)&e);
374 throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
381 std::wostringstream os;
382 os << _W("Invalid index.\n");
383 CoverageInstance::stopChrono((void*)&e);
384 throw InternalError(os.str(), 999, e.getLocation());
388 if (pValue->isDeletable())
390 if (pValue->isContainer())
392 // prevent delete of pReturn in case where
393 // extract not return a clone
394 pReturn->IncreaseRef();
396 pReturn->DecreaseRef();
404 else if (pValue->isFieldExtractionOverloadable())
406 types::typed_list in;
407 types::typed_list out;
409 types::String* pS = new types::String(wstField.c_str());
411 //TODO: in the case where overload is a macro there is no need to incref in
412 // because args will be put in context, removed and killed if required.
413 // But if the overload is a function... it is another story...
416 pValue->IncreaseRef();
419 in.push_back(pValue);
420 types::Callable::ReturnValue Ret = types::Callable::Error;
421 std::wstring stType = pValue->getShortTypeStr();
425 Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
427 catch (const InternalError& ie)
431 //to compatibility with scilab 5 code.
432 //tlist/mlist name are truncated to 8 first character
433 if (stType.size() > 8)
435 Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
439 CoverageInstance::stopChrono((void*)&e);
443 catch (const InternalError& ie)
446 if (pValue->isList())
448 Ret = Overload::call(L"%l_e", in, 1, out, this);
452 CoverageInstance::stopChrono((void*)&e);
458 if (Ret != types::Callable::OK)
462 CoverageInstance::stopChrono((void*)&e);
463 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
472 wchar_t szError[bsiz];
473 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
474 CoverageInstance::stopChrono((void*)&e);
475 throw InternalError(szError, 999, e.getLocation());
478 CoverageInstance::stopChrono((void*)&e);
482 void RunVisitorT<T>::visitprivate(const IfExp &e)
484 CoverageInstance::invokeAndStartChrono((void*)&e);
486 //Create local exec visitor
487 ShortCutVisitor SCTest;
488 bool bTestStatus = false;
493 e.getTest().accept(SCTest);
494 e.getTest().accept(*this);
496 catch (ScilabException &)
498 CoverageInstance::stopChrono((void*)&e);
502 bTestStatus = getResult()->isTrue();
506 if (bTestStatus == true)
508 e.getThen().accept(*this);
510 else if (e.hasElse())
512 const ast::Exp & _else = e.getElse();
513 if (_else.isCommentExp())
515 CoverageInstance::invoke(_else);
519 e.getElse().accept(*this);
523 catch (ScilabException &)
525 CoverageInstance::stopChrono((void*)&e);
530 && ((&e.getElse())->isBreak()
531 || (&e.getThen())->isBreak()))
533 const_cast<IfExp*>(&e)->setBreak();
534 const_cast<Exp*>(&e.getElse())->resetBreak();
535 const_cast<Exp*>(&e.getThen())->resetBreak();
538 if (e.isContinuable()
539 && ((&e.getElse())->isContinue()
540 || (&e.getThen())->isContinue()))
542 const_cast<IfExp*>(&e)->setContinue();
543 const_cast<Exp*>(&e.getElse())->resetContinue();
544 const_cast<Exp*>(&e.getThen())->resetContinue();
548 && ((&e.getElse())->isReturn()
549 || (&e.getThen())->isReturn()))
551 const_cast<IfExp*>(&e)->setReturn();
552 const_cast<Exp*>(&e.getElse())->resetReturn();
553 const_cast<Exp*>(&e.getThen())->resetReturn();
556 CoverageInstance::stopChrono((void*)&e);
560 void RunVisitorT<T>::visitprivate(const WhileExp &e)
562 CoverageInstance::invokeAndStartChrono((void*)&e);
564 //Create local exec visitor
565 ShortCutVisitor SCTest;
569 //manage & and | like && and ||
570 e.getTest().accept(SCTest);
572 e.getTest().accept(*this);
574 catch (ScilabException &)
576 CoverageInstance::stopChrono((void*)&e);
580 types::InternalType* pIT = getResult();
582 while (pIT->isTrue())
587 e.getBody().accept(*this);
589 catch (ScilabException &)
591 CoverageInstance::stopChrono((void*)&e);
595 //clear old result value before evaluate new one
596 if (getResult() != NULL)
598 getResult()->killMe();
601 if (e.getBody().isBreak())
603 const_cast<Exp*>(&(e.getBody()))->resetBreak();
607 if (e.getBody().isReturn())
609 const_cast<WhileExp*>(&e)->setReturn();
610 const_cast<Exp*>(&(e.getBody()))->resetReturn();
614 if (e.getBody().isContinue())
616 const_cast<Exp*>(&(e.getBody()))->resetContinue();
621 e.getTest().accept(*this);
623 catch (ScilabException &)
625 CoverageInstance::stopChrono((void*)&e);
632 //clear result of condition or result of body
634 CoverageInstance::stopChrono((void*)&e);
638 void RunVisitorT<T>::visitprivate(const ForExp &e)
640 CoverageInstance::invokeAndStartChrono((void*)&e);
641 symbol::Context* ctx = symbol::Context::getInstance();
642 //vardec visit increase its result reference
645 e.getVardec().accept(*this);
647 catch (ScilabException &)
649 CoverageInstance::stopChrono((void*)&e);
652 types::InternalType* pIT = getResult();
654 if (pIT->isImplicitList())
657 types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
658 //get IL initial Type
659 types::InternalType * pIL = pVar->getInitalType();
660 //std::cout << "for IL: " << pIL << std::endl;
661 //std::cout << " for IV: " << pIT << std::endl;
663 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
665 if (ctx->isprotected(var))
667 std::wostringstream os;
668 os << _W("Redefining permanent variable.\n");
669 CoverageInstance::stopChrono((void*)&e);
670 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
674 //use ref count to lock var against clear and detect any changes
677 int size = static_cast<int>(pVar->getSize());
678 for (int i = 0; i < size; ++i)
680 //check if loop index has changed, deleted, copy ...
681 if (pIL->getRef() != 2)
683 switch (pIL->getRef())
690 //someone assign me to another var
695 //no need to destroy, it already assign to another var
699 pIL = pVar->getInitalType();
702 //update me ( must decrease ref of a )
703 if (ctx->isprotected(var))
705 std::wostringstream os;
706 os << _W("Redefining permanent variable.\n");
707 CoverageInstance::stopChrono((void*)&e);
708 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
716 pVar->extractValue(i, pIL);
720 e.getBody().accept(*this);
722 catch (const InternalError& ie)
724 //unlock loop index and implicit list
731 CoverageInstance::stopChrono((void*)&e);
735 if (e.getBody().isBreak())
737 const_cast<Exp&>(e.getBody()).resetBreak();
741 if (e.getBody().isContinue())
743 const_cast<Exp&>(e.getBody()).resetContinue();
747 if (e.getBody().isReturn())
749 const_cast<ForExp&>(e).setReturn();
750 const_cast<Exp&>(e.getBody()).resetReturn();
759 else if (pIT->isList())
761 types::List* pL = pIT->getAs<types::List>();
762 const int size = pL->getSize();
763 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
764 for (int i = 0; i < size; ++i)
766 types::InternalType* pNew = pL->get(i);
768 if (ctx->isprotected(var))
770 std::wostringstream os;
771 os << _W("Redefining permanent variable.\n");
772 CoverageInstance::stopChrono((void*)&e);
773 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
779 e.getBody().accept(*this);
781 catch (const InternalError& ie)
787 CoverageInstance::stopChrono((void*)&e);
791 if (e.getBody().isBreak())
793 const_cast<Exp*>(&(e.getBody()))->resetBreak();
797 if (e.getBody().isContinue())
799 const_cast<Exp*>(&(e.getBody()))->resetContinue();
803 if (e.getBody().isReturn())
805 const_cast<ForExp*>(&e)->setReturn();
806 const_cast<Exp&>(e.getBody()).resetReturn();
811 else if (pIT->isGenericType())
813 //Matrix i = [1,3,2,6] or other type
814 types::GenericType* pVar = pIT->getAs<types::GenericType>();
815 if (pVar->getDims() > 2)
819 CoverageInstance::stopChrono((void*)&e);
820 throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
823 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
824 for (int i = 0; i < pVar->getCols(); i++)
826 types::GenericType* pNew = pVar->getColumnValues(i);
831 CoverageInstance::stopChrono((void*)&e);
832 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
835 if (ctx->isprotected(var))
837 std::wostringstream os;
838 os << _W("Redefining permanent variable.\n");
839 CoverageInstance::stopChrono((void*)&e);
840 throw InternalError(os.str(), 999, e.getVardec().getLocation());
846 e.getBody().accept(*this);
848 catch (const InternalError& ie)
854 CoverageInstance::stopChrono((void*)&e);
858 if (e.getBody().isBreak())
860 const_cast<Exp*>(&(e.getBody()))->resetBreak();
864 if (e.getBody().isContinue())
866 const_cast<Exp*>(&(e.getBody()))->resetContinue();
870 if (e.getBody().isReturn())
872 const_cast<ForExp*>(&e)->setReturn();
873 const_cast<Exp&>(e.getBody()).resetReturn();
882 CoverageInstance::stopChrono((void*)&e);
883 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
890 CoverageInstance::stopChrono((void*)&e);
894 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
896 CoverageInstance::invokeAndStartChrono((void*)&e);
899 if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
901 if (ConfigVariable::getEnableDebug() == true)
903 sciprint(_("%s: function is disabled in debug mode.\n"), "resume");
904 CoverageInstance::stopChrono((void*)&e);
909 ConfigVariable::DecreasePauseLevel();
910 CoverageInstance::stopChrono((void*)&e);
915 const_cast<ReturnExp*>(&e)->setReturn();
922 if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
924 CoverageInstance::stopChrono((void*)&e);
925 throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
927 //in case of CallExp, we can return only one values
928 int iSaveExpectedSize = getExpectedSize();
932 e.getExp().accept(*this);
934 catch (ScilabException &)
936 CoverageInstance::stopChrono((void*)&e);
939 setExpectedSize(iSaveExpectedSize);
940 const_cast<ReturnExp*>(&e)->setReturn();
943 CoverageInstance::stopChrono((void*)&e);
947 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
949 CoverageInstance::invokeAndStartChrono((void*)&e);
951 //e.getSelect()->accept(*this);
952 //InternalType* pIT = getResult();
953 //setResult(nullptr);
954 //if (pIT && pIT->isDouble())
956 // Double * pDbl = static_cast<Double *>(pIT);
957 // if (!pDbl->isComplex() && pDbl->getSize() == 1)
960 // if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
962 // Exp * exp = e.getExp(val);
966 // Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
967 // if (e.isBreakable())
969 // const_cast<IntSelectExp*>(&e)->resetBreak();
970 // body->setBreakable();
973 // if (e.isContinuable())
975 // const_cast<IntSelectExp*>(&e)->resetContinue();
976 // body->setContinuable();
979 // if (e.isReturnable())
981 // const_cast<IntSelectExp*>(&e)->resetReturn();
982 // body->setReturnable();
988 // body->accept(*this);
990 // catch (const InternalError& ie)
996 // if (e.isBreakable() && body->isBreak())
998 // const_cast<IntSelectExp*>(&e)->setBreak();
999 // body->resetBreak();
1002 // if (e.isContinuable() && body->isContinue())
1004 // const_cast<IntSelectExp*>(&e)->setContinue();
1005 // body->resetContinue();
1008 // if (e.isReturnable() && body->isReturn())
1010 // const_cast<IntSelectExp*>(&e)->setReturn();
1011 // body->resetReturn();
1022 e.getOriginal()->accept(*this);
1024 catch (ScilabException &)
1026 CoverageInstance::stopChrono((void*)&e);
1030 CoverageInstance::stopChrono((void*)&e);
1034 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
1036 CoverageInstance::invokeAndStartChrono((void*)&e);
1039 e.getSelect()->accept(*this);
1041 catch (ScilabException &)
1043 CoverageInstance::stopChrono((void*)&e);
1046 types::InternalType* pIT = getResult();
1049 if (pIT && pIT->isString())
1051 types::String * pStr = static_cast<types::String *>(pIT);
1052 if (pStr->getSize() == 1)
1054 if (wchar_t * s = pStr->get(0))
1056 const std::wstring ws(s);
1057 Exp * exp = e.getExp(ws);
1061 Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
1062 if (e.isBreakable())
1064 const_cast<StringSelectExp*>(&e)->resetBreak();
1065 body->setBreakable();
1068 if (e.isContinuable())
1070 const_cast<StringSelectExp*>(&e)->resetContinue();
1071 body->setContinuable();
1074 if (e.isReturnable())
1076 const_cast<StringSelectExp*>(&e)->resetReturn();
1077 body->setReturnable();
1083 body->accept(*this);
1085 catch (const InternalError& ie)
1088 CoverageInstance::stopChrono((void*)&e);
1092 if (e.isBreakable() && body->isBreak())
1094 const_cast<StringSelectExp*>(&e)->setBreak();
1098 if (e.isContinuable() && body->isContinue())
1100 const_cast<StringSelectExp*>(&e)->setContinue();
1101 body->resetContinue();
1104 if (e.isReturnable() && body->isReturn())
1106 const_cast<StringSelectExp*>(&e)->setReturn();
1107 body->resetReturn();
1118 e.getOriginal()->accept(*this);
1120 catch (ScilabException &)
1122 CoverageInstance::stopChrono((void*)&e);
1126 CoverageInstance::stopChrono((void*)&e);
1130 void RunVisitorT<T>::visitprivate(const SelectExp &e)
1132 // FIXME : exec select ... case ... else ... end
1133 CoverageInstance::invokeAndStartChrono((void*)&e);
1136 e.getSelect()->accept(*this);
1138 catch (ScilabException &)
1140 CoverageInstance::stopChrono((void*)&e);
1146 types::InternalType* pIT = getResult();
1150 // protect pIT to avoid double free when
1151 // the variable in select is override in the case
1155 exps_t cases = e.getCases();
1156 for (auto exp : cases)
1158 CaseExp * pCase = exp->getAs<CaseExp>();
1161 pCase->getTest()->accept(*this);
1163 catch (ScilabException &)
1165 CoverageInstance::stopChrono((void*)&e);
1168 types::InternalType *pITCase = getResult();
1172 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
1176 else if (*pITCase == *pIT)
1181 pCase->getBody()->accept(*this);
1183 catch (const InternalError& ie)
1187 CoverageInstance::stopChrono((void*)&e);
1191 if (e.isBreakable() && pCase->getBody()->isBreak())
1193 const_cast<SelectExp*>(&e)->setBreak();
1194 pCase->getBody()->resetBreak();
1197 if (e.isContinuable() && pCase->getBody()->isContinue())
1199 const_cast<SelectExp*>(&e)->setContinue();
1200 pCase->getBody()->resetContinue();
1203 if (e.isReturnable() && pCase->getBody()->isReturn())
1205 const_cast<SelectExp*>(&e)->setReturn();
1206 pCase->getBody()->resetReturn();
1219 if (bCase == false && e.getDefaultCase() != NULL)
1224 e.getDefaultCase()->accept(*this);
1226 catch (const InternalError& ie)
1233 CoverageInstance::stopChrono((void*)&e);
1237 if (e.isBreakable() && e.getDefaultCase()->isBreak())
1239 const_cast<SelectExp*>(&e)->setBreak();
1240 e.getDefaultCase()->resetBreak();
1243 if (e.isContinuable() && e.getDefaultCase()->isContinue())
1245 const_cast<SelectExp*>(&e)->setContinue();
1246 e.getDefaultCase()->resetContinue();
1249 if (e.isReturnable() && e.getDefaultCase()->isReturn())
1251 const_cast<SelectExp*>(&e)->setReturn();
1252 e.getDefaultCase()->resetReturn();
1263 CoverageInstance::stopChrono((void*)&e);
1267 void RunVisitorT<T>::visitprivate(const SeqExp &e)
1269 CoverageInstance::invokeAndStartChrono((void*)&e);
1271 for (auto exp : e.getExps())
1273 if (exp->isCommentExp())
1278 if (ConfigVariable::isExecutionBreak())
1280 ConfigVariable::resetExecutionBreak();
1281 if (ConfigVariable::getPromptMode() == 7)
1283 ClearTemporaryPrompt();
1286 StorePrioritaryCommand("pause");
1287 ThreadManagement::WaitForRunMeSignal();
1290 // interrupt me to execute a prioritary command
1291 while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
1293 StaticRunner_launch();
1294 StaticRunner_setInterruptibleCommand(1);
1299 //reset default values
1301 int iExpectedSize = getExpectedSize();
1302 setExpectedSize(-1);
1304 setExpectedSize(iExpectedSize);
1305 types::InternalType * pIT = getResult();
1307 // In case of exec file, set the file name in the Macro to store where it is defined.
1308 int iFileID = ConfigVariable::getExecutedFileID();
1309 if (iFileID && exp->isFunctionDec())
1311 types::InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<FunctionDec>()->getSymbol());
1314 types::Macro* pMacro = pITMacro->getAs<types::Macro>();
1315 const wchar_t* filename = getfile_filename(iFileID);
1316 // scilab.quit is not open with mopen
1317 // in this case filename is NULL because FileManager have not been filled.
1320 pMacro->setFileName(filename);
1327 bool bImplicitCall = false;
1328 if (pIT->isCallable()) //to manage call without ()
1330 types::Callable *pCall = pIT->getAs<types::Callable>();
1331 types::typed_list out;
1332 types::typed_list in;
1333 types::optional_list opt;
1337 //in this case of calling, we can return only one values
1338 int iSaveExpectedSize = getExpectedSize();
1341 pCall->invoke(in, opt, getExpectedSize(), out, e);
1342 setExpectedSize(iSaveExpectedSize);
1344 if (out.size() == 0)
1353 bImplicitCall = true;
1355 catch (const InternalError& ie)
1357 if (ConfigVariable::getLastErrorFunction() == L"")
1359 ConfigVariable::setLastErrorFunction(pCall->getName());
1360 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
1362 CoverageInstance::stopChrono((void*)&e);
1366 else if (pIT->isImplicitList())
1368 //expand implicit when possible
1369 types::ImplicitList* pIL = pIT->getAs<types::ImplicitList>();
1370 if (pIL->isComputable())
1372 types::InternalType* p = pIL->extractFullMatrix();
1380 //don't output Simplevar and empty result
1381 if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
1383 //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
1384 types::InternalType* pITAns = getResult();
1385 symbol::Context::getInstance()->put(m_pAns, pITAns);
1386 if (exp->isVerbose() && ConfigVariable::isPromptShow())
1388 //TODO manage multiple returns
1389 scilabWriteW(L" ans =\n\n");
1390 std::wostringstream ostrName;
1392 VariableToString(pITAns, ostrName.str().c_str());
1399 if (ConfigVariable::getPromptMode() == 7)
1401 Location loc = exp->getLocation();
1402 if (lastLine < loc.first_line)
1405 SetTemporaryPrompt(SCIPROMPT_PAUSE);
1406 ConfigVariable::setScilabCommand(0);
1407 char* pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
1408 if (pcConsoleReadStr) // exec is called from a callback
1410 ThreadManagement::SendConsoleExecDoneSignal();
1412 else // exec is called from the console
1415 pcConsoleReadStr = ConfigVariable::getConsoleReadStr();
1418 if (pcConsoleReadStr && pcConsoleReadStr[0] == 'p' && pcConsoleReadStr[1] == '\0')
1421 ConfigVariable::setExecutionBreak();
1425 lastLine = loc.last_line;
1428 if ((&e)->isBreakable() && exp->isBreak())
1430 const_cast<SeqExp *>(&e)->setBreak();
1435 if ((&e)->isContinuable() && exp->isContinue())
1437 const_cast<SeqExp *>(&e)->setContinue();
1438 exp->resetContinue();
1442 if ((&e)->isReturnable() && exp->isReturn())
1444 const_cast<SeqExp *>(&e)->setReturn();
1449 catch (const InternalError& ie)
1451 ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);
1452 CoverageInstance::stopChrono((void*)&e);
1456 // If something other than NULL is given to setResult, then that would imply
1457 // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
1461 CoverageInstance::stopChrono((void*)&e);
1465 void RunVisitorT<T>::visitprivate(const NotExp &e)
1467 CoverageInstance::invokeAndStartChrono((void*)&e);
1473 e.getExp().accept(*this);
1475 catch (ScilabException &)
1477 CoverageInstance::stopChrono((void*)&e);
1481 types::InternalType * pValue = getResult();
1482 types::InternalType * pReturn = NULL;
1483 if (pValue->neg(pReturn))
1485 if (pValue != pReturn)
1494 // neg returned false so the negation is not possible so we call the overload (%foo_5)
1495 types::typed_list in;
1496 types::typed_list out;
1498 pValue->IncreaseRef();
1499 in.push_back(pValue);
1501 types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1503 if (Ret != types::Callable::OK)
1505 cleanInOut(in, out);
1506 CoverageInstance::stopChrono((void*)&e);
1507 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1513 CoverageInstance::stopChrono((void*)&e);
1517 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1519 CoverageInstance::invokeAndStartChrono((void*)&e);
1522 e.getExp().accept(*this);
1524 catch (ScilabException &)
1526 CoverageInstance::stopChrono((void*)&e);
1530 if (getResultSize() != 1)
1533 wchar_t szError[bsiz];
1534 os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1535 CoverageInstance::stopChrono((void*)&e);
1536 throw InternalError(szError, 999, e.getLocation());
1539 types::InternalType * pValue = getResult();
1540 types::InternalType * pReturn = NULL;
1541 const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1543 if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1545 if (pValue != pReturn)
1551 CoverageInstance::stopChrono((void*)&e);
1557 // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1558 types::typed_list in;
1559 types::typed_list out;
1561 pValue->IncreaseRef();
1562 in.push_back(pValue);
1564 types::Callable::ReturnValue Ret;
1567 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1571 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1574 if (Ret != types::Callable::OK)
1576 cleanInOut(in, out);
1577 CoverageInstance::stopChrono((void*)&e);
1578 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1585 CoverageInstance::stopChrono((void*)&e);
1589 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1591 CoverageInstance::invokeAndStartChrono((void*)&e);
1592 symbol::Context* ctx = symbol::Context::getInstance();
1598 // funcprot(0) : do nothing
1599 // funcprot(1) && warning(on) : warning
1600 //get input parameters list
1601 std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1602 const exps_t & vars = e.getArgs().getVars();
1603 for (const auto var : vars)
1605 pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1608 //get output parameters list
1609 std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1610 const exps_t & rets = e.getReturns().getVars();
1611 for (const auto ret : rets)
1613 pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1616 types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1617 const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1618 pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1620 if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1623 std::wostringstream os;
1624 os << _W("Redefining permanent variable.\n");
1625 CoverageInstance::stopChrono((void*)&e);
1626 throw InternalError(os.str(), 999, e.getLocation());
1629 if (ctx->addMacro(pMacro) == false)
1631 char pstError[1024];
1632 char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1633 os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1634 wchar_t* pwstError = to_wide_string(pstError);
1635 std::wstring wstError(pwstError);
1639 CoverageInstance::stopChrono((void*)&e);
1640 throw InternalError(wstError, 999, e.getLocation());
1643 CoverageInstance::stopChrono((void*)&e);
1647 void RunVisitorT<T>::visitprivate(const ListExp &e)
1649 CoverageInstance::invokeAndStartChrono((void*)&e);
1652 e.getStart().accept(*this);
1654 catch (ScilabException &)
1656 CoverageInstance::stopChrono((void*)&e);
1659 types::GenericType* pITStart = static_cast<types::GenericType*>(getResult());
1660 if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<types::Double>()->isComplex())) &&
1661 pITStart->isList() == false) // list case => call overload
1665 wchar_t szError[bsiz];
1666 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1667 CoverageInstance::stopChrono((void*)&e);
1668 throw InternalError(szError, 999, e.getLocation());
1670 types::InternalType * piStart = pITStart;
1674 e.getStep().accept(*this);
1676 catch (ScilabException &)
1678 CoverageInstance::stopChrono((void*)&e);
1681 types::GenericType* pITStep = static_cast<types::GenericType*>(getResult());
1683 if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<types::Double>()->isComplex())) &&
1684 pITStep->isList() == false) // list case => call overload
1689 wchar_t szError[bsiz];
1690 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1691 CoverageInstance::stopChrono((void*)&e);
1692 throw InternalError(szError, 999, e.getLocation());
1694 types::InternalType* piStep = pITStep;
1698 e.getEnd().accept(*this);
1700 catch (ScilabException &)
1702 CoverageInstance::stopChrono((void*)&e);
1706 types::GenericType* pITEnd = static_cast<types::GenericType*>(getResult());
1708 if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<types::Double>()->isComplex())) &&
1709 pITEnd->isList() == false) // list case => call overload
1715 wchar_t szError[bsiz];
1716 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1717 CoverageInstance::stopChrono((void*)&e);
1718 throw InternalError(szError, 999, e.getLocation());
1720 types::InternalType* piEnd = pITEnd;
1722 ////check if implicitlist is 1:$ to replace by ':'
1723 //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1725 // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1727 // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1728 // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1730 // setResult(new Colon());
1736 //check compatibility
1737 // double : double : double or poly : poly : poly and mix like double : double : poly
1738 if ((piStart->isPoly() || piStart->isDouble()) &&
1739 (piStep->isPoly() || piStep->isDouble()) &&
1740 (piEnd->isPoly() || piEnd->isDouble()))
1742 // No need to kill piStart, ... because Implicit list ctor will incref them
1743 setResult(new types::ImplicitList(piStart, piStep, piEnd));
1744 CoverageInstance::stopChrono((void*)&e);
1748 // int : double or int : int
1749 if (piStart->isInt() &&
1750 (piStep->isDouble() || piStep->isInt()) &&
1753 // check for same int type int8, int 16 ...
1754 if (piStart->getType() == piEnd->getType() &&
1755 (piStart->getType() == piStep->getType() ||
1756 piStep->isDouble()))
1758 // No need to kill piStart, ... because Implicit list ctor will incref them
1759 setResult(new types::ImplicitList(piStart, piStep, piEnd));
1760 CoverageInstance::stopChrono((void*)&e);
1766 types::Callable::ReturnValue Ret;
1767 types::typed_list in;
1768 types::typed_list out;
1770 piStart->IncreaseRef();
1771 in.push_back(piStart);
1775 if (e.hasExplicitStep())
1778 //call overload %typeStart_b_typeStep
1779 piStep->IncreaseRef();
1780 in.push_back(piStep);
1781 piEnd->IncreaseRef();
1782 in.push_back(piEnd);
1783 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, true);
1788 //call overload %typeStart_b_typeEnd
1790 piEnd->IncreaseRef();
1791 in.push_back(piEnd);
1792 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, true);
1795 catch (const InternalError& error)
1798 cleanInOut(in, out);
1799 CoverageInstance::stopChrono((void*)&e);
1803 if (Ret != types::Callable::OK)
1806 cleanInOut(in, out);
1807 CoverageInstance::stopChrono((void*)&e);
1808 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1813 CoverageInstance::stopChrono((void*)&e);
1817 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1822 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1824 CoverageInstance::invokeAndStartChrono((void*)&e);
1827 e.getOriginal()->accept(*this);
1829 catch (ScilabException &)
1831 CoverageInstance::stopChrono((void*)&e);
1837 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1839 CoverageInstance::invokeAndStartChrono((void*)&e);
1840 types::InternalType* pIT = NULL;
1841 types::Double* ad = NULL;
1845 types::Double* xd = NULL;
1849 types::Double* yd = NULL;
1853 //check types and dimensions
1856 const Exp &ye = e.getY();
1861 catch (ScilabException &)
1863 CoverageInstance::stopChrono((void*)&e);
1868 if (pIT->isDouble())
1870 yd = pIT->getAs<types::Double>();
1871 if (yd->getDims() == 2 && yd->isComplex() == false)
1881 e.getOriginal()->accept(*this);
1883 catch (ScilabException &)
1885 CoverageInstance::stopChrono((void*)&e);
1888 CoverageInstance::stopChrono((void*)&e);
1897 e.getOriginal()->accept(*this);
1899 catch (ScilabException &)
1901 CoverageInstance::stopChrono((void*)&e);
1904 CoverageInstance::stopChrono((void*)&e);
1909 const Exp &xe = e.getX();
1914 catch (ScilabException &)
1916 CoverageInstance::stopChrono((void*)&e);
1921 if (pIT->isDouble())
1923 xd = pIT->getAs<types::Double>();
1924 if (xd->isScalar() && xd->isComplex() == false)
1931 else if (xd->getDims() == 2 && xd->isComplex() == false)
1942 e.getOriginal()->accept(*this);
1944 catch (ScilabException &)
1946 CoverageInstance::stopChrono((void*)&e);
1949 CoverageInstance::stopChrono((void*)&e);
1959 e.getOriginal()->accept(*this);
1961 catch (ScilabException &)
1963 CoverageInstance::stopChrono((void*)&e);
1966 CoverageInstance::stopChrono((void*)&e);
1970 const Exp &ae = e.getA();
1975 catch (ScilabException &)
1977 CoverageInstance::stopChrono((void*)&e);
1982 if (pIT->isDouble())
1986 xd = pIT->getAs<types::Double>();
1987 //X is scalar it become A
1989 if (xd->getDims() == 2 && xd->isComplex() == false)
2001 e.getOriginal()->accept(*this);
2003 catch (ScilabException &)
2005 CoverageInstance::stopChrono((void*)&e);
2008 CoverageInstance::stopChrono((void*)&e);
2014 //a is a and it must be scalar
2015 ad = pIT->getAs<types::Double>();
2016 if (/*ad->isScalar() && */ad->isComplex() == false)
2018 ar = ad->getRows(); //1;
2019 ac = ad->getCols();//1;
2028 e.getOriginal()->accept(*this);
2030 catch (ScilabException &)
2032 CoverageInstance::stopChrono((void*)&e);
2047 e.getOriginal()->accept(*this);
2049 catch (ScilabException &)
2051 CoverageInstance::stopChrono((void*)&e);
2054 CoverageInstance::stopChrono((void*)&e);
2068 //Double* od = (Double*)yd->clone();
2069 C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
2074 CoverageInstance::stopChrono((void*)&e);
2077 else if (ac == xr && ar == yr && xc == yc)
2081 C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
2084 CoverageInstance::stopChrono((void*)&e);
2106 e.getOriginal()->accept(*this);
2108 catch (ScilabException &)
2110 CoverageInstance::stopChrono((void*)&e);
2113 CoverageInstance::stopChrono((void*)&e);
2119 void RunVisitorT<T>::visitprivate(const TryCatchExp &e)
2121 CoverageInstance::invokeAndStartChrono((void*)&e);
2122 //save current prompt mode
2123 int oldVal = ConfigVariable::getSilentError();
2124 int oldMode = ConfigVariable::getPromptMode();
2125 //set mode silent for errors
2126 ConfigVariable::setSilentError(1);
2128 symbol::Context* pCtx = symbol::Context::getInstance();
2131 int scope = pCtx->getScopeLevel();
2132 int level = ConfigVariable::getRecursionLevel();
2135 e.getTry().accept(*this);
2136 //restore previous prompt mode
2137 ConfigVariable::setSilentError(oldVal);
2139 catch (const RecursionException& /* re */)
2141 ConfigVariable::setPromptMode(oldMode);
2143 //close opened scope during try
2144 while (pCtx->getScopeLevel() > scope)
2149 //decrease recursion to init value and close where
2150 while (ConfigVariable::getRecursionLevel() > level)
2152 ConfigVariable::where_end();
2153 ConfigVariable::decreaseRecursion();
2156 //print msg about recursion limit and trigger an error
2158 os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
2159 CoverageInstance::stopChrono((void*)&e);
2160 throw ast::InternalError(sz);
2164 catch (const InternalError& /* ie */)
2166 //restore previous prompt mode
2167 ConfigVariable::setSilentError(oldVal);
2169 ConfigVariable::setLastErrorCall();
2170 // reset call stack filled when error occured
2171 ConfigVariable::resetWhereError();
2174 e.getCatch().accept(*this);
2176 catch (ScilabException &)
2178 CoverageInstance::stopChrono((void*)&e);
2182 CoverageInstance::stopChrono((void*)&e);
2186 } /* namespace ast */
2188 #include "run_CallExp.hpp"
2189 #include "run_MatrixExp.hpp"
2190 #include "run_OpExp.hpp"
2191 #include "run_AssignExp.hpp"
2193 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
2194 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
2195 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
2196 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;