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"
49 #include "os_string.h"
50 #include "elem_common.h"
51 #include "storeCommand.h"
57 void RunVisitorT<T>::visitprivate(const CellExp &e)
59 exps_t::const_iterator row;
60 exps_t::const_iterator col;
63 exps_t lines = e.getLines();
65 for (row = lines.begin() ; row != lines.end() ; ++row )
67 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
70 iColMax = static_cast<int>(cols.size());
73 if (iColMax != static_cast<int>(cols.size()))
75 std::wostringstream os;
76 os << _W("inconsistent row/column dimensions\n");
77 //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
78 throw InternalError(os.str(), 999, (*row)->getLocation());
83 types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
88 //insert items in cell
89 for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
91 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
92 for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
94 (*col)->accept(*this);
95 types::InternalType *pIT = getResult();
96 if (pIT->isImplicitList())
98 types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
115 void RunVisitorT<T>::visitprivate(const FieldExp &e)
121 if (!e.getTail()->isSimpleVar())
123 wchar_t szError[bsiz];
124 os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
125 throw InternalError(szError, 999, e.getLocation());
130 e.getHead()->accept(*this);
132 catch (const InternalError& error)
137 if (getResult() == NULL)
139 wchar_t szError[bsiz];
140 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
141 throw InternalError(szError, 999, e.getLocation());
144 // TODO: handle case where getSize() > 1
145 // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
147 if (getResultSize() > 1)
150 wchar_t szError[bsiz];
151 os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
152 throw InternalError(szError, 999, e.getLocation());
155 SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
156 std::wstring wstField = psvRightMember->getSymbol().getName();
157 types::InternalType * pValue = getResult();
158 types::InternalType * pReturn = NULL;
163 if (pValue->isGenericType() || pValue->isUserType())
165 ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
168 catch (std::wstring & err)
171 throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
178 std::wostringstream os;
179 os << _W("Invalid index.\n");
180 throw InternalError(os.str(), 999, e.getLocation());
184 if (pValue->isDeletable())
186 if (pValue->isContainer())
188 // prevent delete of pReturn in case where
189 // extract not return a clone
190 pReturn->IncreaseRef();
192 pReturn->DecreaseRef();
200 else if (pValue->isFieldExtractionOverloadable())
202 types::typed_list in;
203 types::typed_list out;
205 types::String* pS = new types::String(wstField.c_str());
207 //TODO: in the case where overload is a macro there is no need to incref in
208 // because args will be put in context, removed and killed if required.
209 // But if the overload is a function... it is another story...
212 pValue->IncreaseRef();
215 in.push_back(pValue);
216 types::Callable::ReturnValue Ret = types::Callable::Error;
217 std::wstring stType = pValue->getShortTypeStr();
221 Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
223 catch (const InternalError& ie)
227 //to compatibility with scilab 5 code.
228 //tlist/mlist name are truncated to 8 first character
229 if (stType.size() > 8)
231 Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
238 catch (const InternalError& ie)
241 if (pValue->isList())
243 Ret = Overload::call(L"%l_e", in, 1, out, this);
252 if (Ret != types::Callable::OK)
256 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
265 wchar_t szError[bsiz];
266 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
267 throw InternalError(szError, 999, e.getLocation());
272 void RunVisitorT<T>::visitprivate(const IfExp &e)
274 //Create local exec visitor
275 ShortCutVisitor SCTest;
276 bool bTestStatus = false;
279 e.getTest().accept(SCTest);
280 e.getTest().accept(*this);
282 bTestStatus = getResult()->isTrue();
284 if (bTestStatus == true)
286 e.getThen().accept(*this);
288 else if (e.hasElse())
290 e.getElse().accept(*this);
294 && ( (&e.getElse())->isBreak()
295 || (&e.getThen())->isBreak() ))
297 const_cast<IfExp*>(&e)->setBreak();
298 const_cast<Exp*>(&e.getElse())->resetBreak();
299 const_cast<Exp*>(&e.getThen())->resetBreak();
302 if (e.isContinuable()
303 && ( (&e.getElse())->isContinue()
304 || (&e.getThen())->isContinue() ))
306 const_cast<IfExp*>(&e)->setContinue();
307 const_cast<Exp*>(&e.getElse())->resetContinue();
308 const_cast<Exp*>(&e.getThen())->resetContinue();
312 && ( (&e.getElse())->isReturn()
313 || (&e.getThen())->isReturn() ))
315 const_cast<IfExp*>(&e)->setReturn();
316 const_cast<Exp*>(&e.getElse())->resetReturn();
317 const_cast<Exp*>(&e.getThen())->resetReturn();
322 void RunVisitorT<T>::visitprivate(const WhileExp &e)
325 //Create local exec visitor
326 ShortCutVisitor SCTest;
328 //manage & and | like && and ||
329 e.getTest().accept(SCTest);
331 e.getTest().accept(*this);
333 types::InternalType* pIT = getResult();
335 while (pIT->isTrue())
338 e.getBody().accept(*this);
340 //clear old result value before evaluate new one
341 if (getResult() != NULL)
343 getResult()->killMe();
346 if (e.getBody().isBreak())
348 const_cast<Exp*>(&(e.getBody()))->resetBreak();
352 if (e.getBody().isReturn())
354 const_cast<WhileExp*>(&e)->setReturn();
355 const_cast<Exp*>(&(e.getBody()))->resetReturn();
359 if (e.getBody().isContinue())
361 const_cast<Exp*>(&(e.getBody()))->resetContinue();
364 e.getTest().accept(*this);
369 //clear result of condition or result of body
374 void RunVisitorT<T>::visitprivate(const ForExp &e)
376 symbol::Context* ctx = symbol::Context::getInstance();
377 //vardec visit increase its result reference
378 e.getVardec().accept(*this);
379 types::InternalType* pIT = getResult();
381 if (pIT->isImplicitList())
384 types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
385 //get IL initial Type
386 types::InternalType * pIL = pVar->getInitalType();
387 //std::cout << "for IL: " << pIL << std::endl;
388 //std::cout << " for IV: " << pIT << std::endl;
390 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
392 if (ctx->isprotected(var))
394 std::wostringstream os;
395 os << _W("Redefining permanent variable.\n");
396 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
400 //use ref count to lock var against clear and detect any changes
403 int size = static_cast<int>(pVar->getSize());
404 for (int i = 0; i < size; ++i)
406 //check if loop index has changed, deleted, copy ...
407 if (pIL->getRef() != 2)
409 switch (pIL->getRef())
416 //someone assign me to another var
421 //no need to destroy, it already assign to another var
425 pIL = pVar->getInitalType();
428 //update me ( must decrease ref of a )
429 if (ctx->isprotected(var))
431 std::wostringstream os;
432 os << _W("Redefining permanent variable.\n");
433 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
441 pVar->extractValue(i, pIL);
445 e.getBody().accept(*this);
447 catch (const InternalError& ie)
449 //unlock loop index and implicit list
459 if (e.getBody().isBreak())
461 const_cast<Exp&>(e.getBody()).resetBreak();
465 if (e.getBody().isContinue())
467 const_cast<Exp&>(e.getBody()).resetContinue();
471 if (e.getBody().isReturn())
473 const_cast<ForExp&>(e).setReturn();
474 const_cast<Exp&>(e.getBody()).resetReturn();
483 else if (pIT->isList())
485 types::List* pL = pIT->getAs<types::List>();
486 const int size = pL->getSize();
487 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
488 for (int i = 0; i < size; ++i)
490 types::InternalType* pNew = pL->get(i);
492 if (ctx->isprotected(var))
494 std::wostringstream os;
495 os << _W("Redefining permanent variable.\n");
496 throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
502 e.getBody().accept(*this);
504 catch (const InternalError& ie)
513 if (e.getBody().isBreak())
515 const_cast<Exp*>(&(e.getBody()))->resetBreak();
519 if (e.getBody().isContinue())
521 const_cast<Exp*>(&(e.getBody()))->resetContinue();
525 if (e.getBody().isReturn())
527 const_cast<ForExp*>(&e)->setReturn();
528 const_cast<Exp&>(e.getBody()).resetReturn();
533 else if (pIT->isGenericType())
535 //Matrix i = [1,3,2,6] or other type
536 types::GenericType* pVar = pIT->getAs<types::GenericType>();
537 if (pVar->getDims() > 2)
541 throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
544 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
545 for (int i = 0; i < pVar->getCols(); i++)
547 types::GenericType* pNew = pVar->getColumnValues(i);
552 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
555 if (ctx->isprotected(var))
557 std::wostringstream os;
558 os << _W("Redefining permanent variable.\n");
559 throw InternalError(os.str(), 999, e.getVardec().getLocation());
565 e.getBody().accept(*this);
567 catch (const InternalError& ie)
576 if (e.getBody().isBreak())
578 const_cast<Exp*>(&(e.getBody()))->resetBreak();
582 if (e.getBody().isContinue())
584 const_cast<Exp*>(&(e.getBody()))->resetContinue();
588 if (e.getBody().isReturn())
590 const_cast<ForExp*>(&e)->setReturn();
591 const_cast<Exp&>(e.getBody()).resetReturn();
600 throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
610 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
614 if (ConfigVariable::getEnableDebug() == true)
616 sciprint(_("%s: function is disable in debug mode.\n"), "resume");
620 if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
623 ConfigVariable::DecreasePauseLevel();
628 const_cast<ReturnExp*>(&e)->setReturn();
635 //in case of CallExp, we can return only one values
636 int iSaveExpectedSize = getExpectedSize();
638 e.getExp().accept(*this);
639 setExpectedSize(iSaveExpectedSize);
640 const_cast<ReturnExp*>(&e)->setReturn();
645 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
648 //e.getSelect()->accept(*this);
649 //InternalType* pIT = getResult();
650 //setResult(nullptr);
651 //if (pIT && pIT->isDouble())
653 // Double * pDbl = static_cast<Double *>(pIT);
654 // if (!pDbl->isComplex() && pDbl->getSize() == 1)
657 // if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
659 // Exp * exp = e.getExp(val);
663 // Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
664 // if (e.isBreakable())
666 // const_cast<IntSelectExp*>(&e)->resetBreak();
667 // body->setBreakable();
670 // if (e.isContinuable())
672 // const_cast<IntSelectExp*>(&e)->resetContinue();
673 // body->setContinuable();
676 // if (e.isReturnable())
678 // const_cast<IntSelectExp*>(&e)->resetReturn();
679 // body->setReturnable();
685 // body->accept(*this);
687 // catch (const InternalError& ie)
693 // if (e.isBreakable() && body->isBreak())
695 // const_cast<IntSelectExp*>(&e)->setBreak();
696 // body->resetBreak();
699 // if (e.isContinuable() && body->isContinue())
701 // const_cast<IntSelectExp*>(&e)->setContinue();
702 // body->resetContinue();
705 // if (e.isReturnable() && body->isReturn())
707 // const_cast<IntSelectExp*>(&e)->setReturn();
708 // body->resetReturn();
717 e.getOriginal()->accept(*this);
722 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
724 e.getSelect()->accept(*this);
725 types::InternalType* pIT = getResult();
728 if (pIT && pIT->isString())
730 types::String * pStr = static_cast<types::String *>(pIT);
731 if (pStr->getSize() == 1)
733 if (wchar_t * s = pStr->get(0))
735 const std::wstring ws(s);
736 Exp * exp = e.getExp(ws);
740 Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
743 const_cast<StringSelectExp*>(&e)->resetBreak();
744 body->setBreakable();
747 if (e.isContinuable())
749 const_cast<StringSelectExp*>(&e)->resetContinue();
750 body->setContinuable();
753 if (e.isReturnable())
755 const_cast<StringSelectExp*>(&e)->resetReturn();
756 body->setReturnable();
764 catch (const InternalError& ie)
770 if (e.isBreakable() && body->isBreak())
772 const_cast<StringSelectExp*>(&e)->setBreak();
776 if (e.isContinuable() && body->isContinue())
778 const_cast<StringSelectExp*>(&e)->setContinue();
779 body->resetContinue();
782 if (e.isReturnable() && body->isReturn())
784 const_cast<StringSelectExp*>(&e)->setReturn();
794 e.getOriginal()->accept(*this);
799 void RunVisitorT<T>::visitprivate(const SelectExp &e)
801 // FIXME : exec select ... case ... else ... end
802 e.getSelect()->accept(*this);
805 types::InternalType* pIT = getResult();
809 // protect pIT to avoid double free when
810 // the variable in select is override in the case
814 exps_t cases = e.getCases();
815 for (auto exp : cases)
817 CaseExp* pCase = exp->getAs<CaseExp>();
818 pCase->getTest()->accept(*this);
819 types::InternalType *pITCase = getResult();
823 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
827 else if (*pITCase == *pIT)
832 pCase->getBody()->accept(*this);
834 catch (const InternalError& ie)
841 if (e.isBreakable() && pCase->getBody()->isBreak())
843 const_cast<SelectExp*>(&e)->setBreak();
844 pCase->getBody()->resetBreak();
847 if (e.isContinuable() && pCase->getBody()->isContinue())
849 const_cast<SelectExp*>(&e)->setContinue();
850 pCase->getBody()->resetContinue();
853 if (e.isReturnable() && pCase->getBody()->isReturn())
855 const_cast<SelectExp*>(&e)->setReturn();
856 pCase->getBody()->resetReturn();
869 if (bCase == false && e.getDefaultCase() != NULL)
874 e.getDefaultCase()->accept(*this);
876 catch (const InternalError& ie)
886 if (e.isBreakable() && e.getDefaultCase()->isBreak())
888 const_cast<SelectExp*>(&e)->setBreak();
889 e.getDefaultCase()->resetBreak();
892 if (e.isContinuable() && e.getDefaultCase()->isContinue())
894 const_cast<SelectExp*>(&e)->setContinue();
895 e.getDefaultCase()->resetContinue();
898 if (e.isReturnable() && e.getDefaultCase()->isReturn())
900 const_cast<SelectExp*>(&e)->setReturn();
901 e.getDefaultCase()->resetReturn();
915 void RunVisitorT<T>::visitprivate(const SeqExp &e)
917 for (auto exp : e.getExps())
919 if (exp->isCommentExp())
924 if (ConfigVariable::isExecutionBreak())
926 ConfigVariable::resetExecutionBreak();
927 StorePrioritaryCommand("pause");
930 // interrupt me to execute a prioritary command
931 while (StaticRunner_isInterruptibleCommand() == 1 && StaticRunner_isRunnerAvailable() == 1)
933 StaticRunner_launch();
934 StaticRunner_setInterruptibleCommand(1);
941 //reset default values
943 int iExpectedSize = getExpectedSize();
946 setExpectedSize(iExpectedSize);
947 types::InternalType * pIT = getResult();
949 // In case of exec file, set the file name in the Macro to store where it is defined.
950 int iFileID = ConfigVariable::getExecutedFileID();
951 if (iFileID && exp->isFunctionDec())
953 types::InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<FunctionDec>()->getSymbol());
956 types::Macro* pMacro = pITMacro->getAs<types::Macro>();
957 const wchar_t* filename = getfile_filename(iFileID);
958 // scilab.quit is not open with mopen
959 // in this case filename is NULL because FileManager have not been filled.
962 pMacro->setFileName(filename);
969 bool bImplicitCall = false;
970 if (pIT->isCallable()) //to manage call without ()
972 types::Callable *pCall = pIT->getAs<types::Callable>();
973 types::typed_list out;
974 types::typed_list in;
975 types::optional_list opt;
979 //in this case of calling, we can return only one values
980 int iSaveExpectedSize = getExpectedSize();
983 pCall->invoke(in, opt, getExpectedSize(), out, e);
984 setExpectedSize(iSaveExpectedSize);
995 bImplicitCall = true;
997 catch (const InternalError& ie)
999 if (ConfigVariable::getLastErrorFunction() == L"")
1001 ConfigVariable::setLastErrorFunction(pCall->getName());
1002 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
1009 //don't output Simplevar and empty result
1010 if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
1012 //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
1013 types::InternalType* pITAns = getResult();
1014 symbol::Context::getInstance()->put(m_pAns, pITAns);
1015 if (exp->isVerbose() && ConfigVariable::isPromptShow())
1017 //TODO manage multiple returns
1018 scilabWriteW(L" ans =\n\n");
1019 std::wostringstream ostrName;
1021 VariableToString(pITAns, ostrName.str().c_str());
1028 if ((&e)->isBreakable() && exp->isBreak())
1030 const_cast<SeqExp *>(&e)->setBreak();
1035 if ((&e)->isContinuable() && exp->isContinue())
1037 const_cast<SeqExp *>(&e)->setContinue();
1038 exp->resetContinue();
1042 if ((&e)->isReturnable() && exp->isReturn())
1044 const_cast<SeqExp *>(&e)->setReturn();
1049 catch (const InternalError& ie)
1051 ConfigVariable::fillWhereError(ie.GetErrorLocation().first_line);
1055 // If something other than NULL is given to setResult, then that would imply
1056 // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
1062 void RunVisitorT<T>::visitprivate(const NotExp &e)
1067 e.getExp().accept(*this);
1069 types::InternalType * pValue = getResult();
1070 types::InternalType * pReturn = NULL;
1071 if (pValue->neg(pReturn))
1073 if (pValue != pReturn)
1082 // neg returned false so the negation is not possible so we call the overload (%foo_5)
1083 types::typed_list in;
1084 types::typed_list out;
1086 pValue->IncreaseRef();
1087 in.push_back(pValue);
1089 types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1091 if (Ret != types::Callable::OK)
1093 cleanInOut(in, out);
1094 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1103 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1105 e.getExp().accept(*this);
1107 if (getResultSize() != 1)
1110 wchar_t szError[bsiz];
1111 os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1112 throw InternalError(szError, 999, e.getLocation());
1115 types::InternalType * pValue = getResult();
1116 types::InternalType * pReturn = NULL;
1117 const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1119 if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1121 if (pValue != pReturn)
1132 // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1133 types::typed_list in;
1134 types::typed_list out;
1136 pValue->IncreaseRef();
1137 in.push_back(pValue);
1139 types::Callable::ReturnValue Ret;
1142 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1146 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1149 if (Ret != types::Callable::OK)
1151 cleanInOut(in, out);
1152 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1161 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1163 symbol::Context* ctx = symbol::Context::getInstance();
1169 // funcprot(0) : do nothing
1170 // funcprot(1) && warning(on) : warning
1171 //get input parameters list
1172 std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1173 const exps_t & vars = e.getArgs().getVars();
1174 for (const auto var : vars)
1176 pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1179 //get output parameters list
1180 std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1181 const exps_t & rets = e.getReturns().getVars();
1182 for (const auto ret : rets)
1184 pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1187 types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1188 const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1189 pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1191 bool bEquals = false;
1192 int iFuncProt = ConfigVariable::getFuncprot();
1195 types::InternalType* pITFunc = ctx->get(((FunctionDec&)e).getStack());
1196 if (pITFunc && pITFunc->isCallable())
1198 if (pITFunc->isMacroFile())
1200 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1201 bEquals = *pMF->getMacro() == *pMacro;
1203 else if (pITFunc->isMacro())
1205 types::Macro* pM = pITFunc->getAs<types::Macro>();
1206 bEquals = *pM == *pMacro;
1211 bEquals = true; //avoid msg but keep assignation
1215 if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1217 wchar_t pwstFuncName[1024];
1218 os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1219 char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1222 sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1226 else if (bEquals == false && iFuncProt == 2)
1228 char pstError[1024];
1229 char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1230 os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1231 wchar_t* pwstError = to_wide_string(pstError);
1232 std::wstring wstError(pwstError);
1236 throw InternalError(wstError, 999, e.getLocation());
1240 if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1243 std::wostringstream os;
1244 os << _W("Redefining permanent variable.\n");
1245 throw InternalError(os.str(), 999, e.getLocation());
1248 ctx->addMacro(pMacro);
1253 void RunVisitorT<T>::visitprivate(const ListExp &e)
1255 e.getStart().accept(*this);
1256 types::GenericType* pITStart = static_cast<types::GenericType*>(getResult());
1257 if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<types::Double>()->isComplex())) &&
1258 pITStart->isList() == false) // list case => call overload
1261 wchar_t szError[bsiz];
1262 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1263 throw InternalError(szError, 999, e.getLocation());
1265 types::InternalType * piStart = pITStart;
1267 e.getStep().accept(*this);
1268 types::GenericType* pITStep = static_cast<types::GenericType*>(getResult());
1269 if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<types::Double>()->isComplex())) &&
1270 pITStep->isList() == false) // list case => call overload
1274 wchar_t szError[bsiz];
1275 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1276 throw InternalError(szError, 999, e.getLocation());
1278 types::InternalType* piStep = pITStep;
1280 e.getEnd().accept(*this);
1281 types::GenericType* pITEnd = static_cast<types::GenericType*>(getResult());
1282 if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<types::Double>()->isComplex())) &&
1283 pITEnd->isList() == false) // list case => call overload
1288 wchar_t szError[bsiz];
1289 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1290 throw InternalError(szError, 999, e.getLocation());
1292 types::InternalType* piEnd = pITEnd;
1294 ////check if implicitlist is 1:$ to replace by ':'
1295 //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1297 // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1299 // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1300 // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1302 // setResult(new Colon());
1308 //check compatibility
1309 // double : double : double or poly : poly : poly and mix like double : double : poly
1310 if ((piStart->isPoly() || piStart->isDouble()) &&
1311 (piStep->isPoly() || piStep->isDouble()) &&
1312 (piEnd->isPoly() || piEnd->isDouble()))
1314 // No need to kill piStart, ... because Implicit list ctor will incref them
1315 setResult(new types::ImplicitList(piStart, piStep, piEnd));
1319 // int : double or int : int
1320 if ( piStart->isInt() &&
1321 (piStep->isDouble() || piStep->isInt()) &&
1324 // check for same int type int8, int 16 ...
1325 if (piStart->getType() == piEnd->getType() &&
1326 (piStart->getType() == piStep->getType() ||
1327 piStep->isDouble()))
1329 // No need to kill piStart, ... because Implicit list ctor will incref them
1330 setResult(new types::ImplicitList(piStart, piStep, piEnd));
1336 types::Callable::ReturnValue Ret;
1337 types::typed_list in;
1338 types::typed_list out;
1340 piStart->IncreaseRef();
1341 in.push_back(piStart);
1345 if (e.hasExplicitStep())
1348 //call overload %typeStart_b_typeStep
1349 piStep->IncreaseRef();
1350 in.push_back(piStep);
1351 piEnd->IncreaseRef();
1352 in.push_back(piEnd);
1353 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, true);
1358 //call overload %typeStart_b_typeEnd
1360 piEnd->IncreaseRef();
1361 in.push_back(piEnd);
1362 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, true);
1365 catch (const InternalError& error)
1367 cleanInOut(in, out);
1371 if (Ret != types::Callable::OK)
1373 cleanInOut(in, out);
1374 throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1382 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1387 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1389 e.getOriginal()->accept(*this);
1393 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1395 types::InternalType* pIT = NULL;
1396 types::Double* ad = NULL;
1400 types::Double* xd = NULL;
1404 types::Double* yd = NULL;
1408 //check types and dimensions
1411 const Exp &ye = e.getY();
1414 if (pIT->isDouble())
1416 yd = pIT->getAs<types::Double>();
1417 if (yd->getDims() == 2 && yd->isComplex() == false)
1425 e.getOriginal()->accept(*this);
1432 e.getOriginal()->accept(*this);
1437 const Exp &xe = e.getX();
1441 if (pIT->isDouble())
1443 xd = pIT->getAs<types::Double>();
1444 if (xd->isScalar() && xd->isComplex() == false)
1451 else if (xd->getDims() == 2 && xd->isComplex() == false)
1460 e.getOriginal()->accept(*this);
1468 e.getOriginal()->accept(*this);
1472 const Exp &ae = e.getA();
1476 if (pIT->isDouble())
1480 xd = pIT->getAs<types::Double>();
1481 //X is scalar it become A
1483 if (xd->getDims() == 2 && xd->isComplex() == false)
1493 e.getOriginal()->accept(*this);
1499 //a is a and it must be scalar
1500 ad = pIT->getAs<types::Double>();
1501 if (/*ad->isScalar() && */ad->isComplex() == false)
1503 ar = ad->getRows(); //1;
1504 ac = ad->getCols();//1;
1511 e.getOriginal()->accept(*this);
1521 e.getOriginal()->accept(*this);
1535 //Double* od = (Double*)yd->clone();
1536 C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1543 else if (ac == xr && ar == yr && xc == yc)
1547 C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1569 e.getOriginal()->accept(*this);
1573 } /* namespace ast */
1575 #include "run_CallExp.hpp"
1576 #include "run_MatrixExp.hpp"
1577 #include "run_OpExp.hpp"
1578 #include "run_AssignExp.hpp"
1580 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1581 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1582 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
1583 template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;