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
14 #if defined(DEBUG_VLD) && defined(_DEBUG)
20 #include "runvisitor.hxx"
21 #include "execvisitor.hxx"
22 #include "stepvisitor.hxx"
23 #include "timedvisitor.hxx"
24 #include "shortcutvisitor.hxx"
25 #include "printvisitor.hxx"
26 #include "mutevisitor.hxx"
27 //#include "AnalysisVisitor.hxx"
29 #include "visitor_common.hxx"
31 #include "context.hxx"
32 #include "generic_operations.hxx"
33 #include "types_or.hxx"
34 #include "types_and.hxx"
35 #include "localization.hxx"
37 #include "macrofile.hxx"
39 #include "filemanager_interface.h"
42 #include "threadmanagement.hxx"
47 #include "os_string.h"
48 #include "elem_common.h"
54 void RunVisitorT<T>::visitprivate(const CellExp &e)
56 exps_t::const_iterator row;
57 exps_t::const_iterator col;
60 exps_t lines = e.getLines();
62 for (row = lines.begin() ; row != lines.end() ; ++row )
64 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
67 iColMax = static_cast<int>(cols.size());
70 if (iColMax != static_cast<int>(cols.size()))
72 std::wostringstream os;
73 os << _W("inconsistent row/column dimensions\n");
74 //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
75 throw ScilabError(os.str(), 999, (*row)->getLocation());
80 types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
85 //insert items in cell
86 for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
88 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
89 for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
91 (*col)->accept(*this);
92 InternalType *pIT = getResult();
93 if (pIT->isImplicitList())
95 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
112 void RunVisitorT<T>::visitprivate(const FieldExp &e)
118 if (!e.getTail()->isSimpleVar())
120 wchar_t szError[bsiz];
121 os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
122 throw ScilabError(szError, 999, e.getLocation());
127 e.getHead()->accept(*this);
129 catch (const ScilabError& error)
134 if (getResult() == NULL)
136 wchar_t szError[bsiz];
137 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
138 throw ScilabError(szError, 999, e.getLocation());
141 // TODO: handle case where getSize() > 1
142 // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
144 if (getResultSize() > 1)
147 wchar_t szError[bsiz];
148 os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
149 throw ScilabError(szError, 999, e.getLocation());
152 SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
153 std::wstring wstField = psvRightMember->getSymbol().getName();
154 InternalType * pValue = getResult();
155 InternalType * pReturn = NULL;
160 if (pValue->isGenericType() || pValue->isUserType())
162 ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
165 catch (std::wstring & err)
168 throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
175 std::wostringstream os;
176 os << _W("Invalid index.\n");
177 throw ScilabError(os.str(), 999, e.getLocation());
181 if (pValue->isDeletable())
183 if (pValue->isContainer())
185 // prevent delete of pReturn in case where
186 // extract not return a clone
187 pReturn->IncreaseRef();
189 pReturn->DecreaseRef();
197 else if (pValue->isFieldExtractionOverloadable())
199 types::typed_list in;
200 types::typed_list out;
202 String* pS = new String(wstField.c_str());
204 //TODO: in the case where overload is a macro there is no need to incref in
205 // because args will be put in context, removed and killed if required.
206 // But if the overload is a function... it is another story...
209 pValue->IncreaseRef();
212 in.push_back(pValue);
213 Callable::ReturnValue Ret = Callable::Error;
214 std::wstring stType = pValue->getShortTypeStr();
218 Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
220 catch (ast::ScilabError & se)
224 //to compatibility with scilab 5 code.
225 //tlist/mlist name are truncated to 8 first character
226 if (stType.size() > 8)
228 Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
235 catch (ast::ScilabError & se)
238 if (pValue->isList())
240 Ret = Overload::call(L"%l_e", in, 1, out, this);
249 if (Ret != Callable::OK)
253 throw ScilabError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
262 wchar_t szError[bsiz];
263 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
264 throw ScilabError(szError, 999, e.getLocation());
269 void RunVisitorT<T>::visitprivate(const IfExp &e)
271 //Create local exec visitor
272 ShortCutVisitor SCTest;
273 bool bTestStatus = false;
276 e.getTest().accept(SCTest);
277 e.getTest().accept(*this);
279 bTestStatus = getResult()->isTrue();
281 if (bTestStatus == true)
283 e.getThen().accept(*this);
285 else if (e.hasElse())
287 e.getElse().accept(*this);
291 && ( (&e.getElse())->isBreak()
292 || (&e.getThen())->isBreak() ))
294 const_cast<IfExp*>(&e)->setBreak();
295 const_cast<Exp*>(&e.getElse())->resetBreak();
296 const_cast<Exp*>(&e.getThen())->resetBreak();
299 if (e.isContinuable()
300 && ( (&e.getElse())->isContinue()
301 || (&e.getThen())->isContinue() ))
303 const_cast<IfExp*>(&e)->setContinue();
304 const_cast<Exp*>(&e.getElse())->resetContinue();
305 const_cast<Exp*>(&e.getThen())->resetContinue();
309 && ( (&e.getElse())->isReturn()
310 || (&e.getThen())->isReturn() ))
312 const_cast<IfExp*>(&e)->setReturn();
313 const_cast<Exp*>(&e.getElse())->resetReturn();
314 const_cast<Exp*>(&e.getThen())->resetReturn();
319 void RunVisitorT<T>::visitprivate(const WhileExp &e)
322 //Create local exec visitor
323 ShortCutVisitor SCTest;
325 //manage & and | like && and ||
326 e.getTest().accept(SCTest);
328 e.getTest().accept(*this);
330 InternalType* pIT = getResult();
332 while (pIT->isTrue())
335 e.getBody().accept(*this);
337 //clear old result value before evaluate new one
338 if (getResult() != NULL)
340 getResult()->killMe();
343 if (e.getBody().isBreak())
345 const_cast<Exp*>(&(e.getBody()))->resetBreak();
349 if (e.getBody().isReturn())
351 const_cast<WhileExp*>(&e)->setReturn();
352 const_cast<Exp*>(&(e.getBody()))->resetReturn();
356 if (e.getBody().isContinue())
358 const_cast<Exp*>(&(e.getBody()))->resetContinue();
361 e.getTest().accept(*this);
366 //clear result of condition or result of body
371 void RunVisitorT<T>::visitprivate(const ForExp &e)
373 symbol::Context* ctx = symbol::Context::getInstance();
374 //vardec visit increase its result reference
375 e.getVardec().accept(*this);
376 InternalType* pIT = getResult();
378 if (pIT->isImplicitList())
381 ImplicitList* pVar = pIT->getAs<ImplicitList>();
382 //get IL initial Type
383 InternalType * pIL = pVar->getInitalType();
384 //std::cout << "for IL: " << pIL << std::endl;
385 //std::cout << " for IV: " << pIT << std::endl;
387 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
389 if (ctx->isprotected(var))
391 std::wostringstream os;
392 os << _W("Redefining permanent variable.\n");
393 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
397 //use ref count to lock var against clear and detect any changes
400 int size = static_cast<int>(pVar->getSize());
401 for (int i = 0; i < size; ++i)
403 //check if loop index has changed, deleted, copy ...
404 if (pIL->getRef() != 2)
406 switch (pIL->getRef())
413 //someone assign me to another var
418 //no need to destroy, it already assign to another var
422 pIL = pVar->getInitalType();
425 //update me ( must decrease ref of a )
426 if (ctx->isprotected(var))
428 std::wostringstream os;
429 os << _W("Redefining permanent variable.\n");
430 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
438 pVar->extractValue(i, pIL);
442 e.getBody().accept(*this);
444 catch (ScilabMessage& sm)
446 //unlock loop index and implicit list
456 if (e.getBody().isBreak())
458 const_cast<Exp&>(e.getBody()).resetBreak();
462 if (e.getBody().isContinue())
464 const_cast<Exp&>(e.getBody()).resetContinue();
468 if (e.getBody().isReturn())
470 const_cast<ForExp&>(e).setReturn();
471 const_cast<Exp&>(e.getBody()).resetReturn();
480 else if (pIT->isList())
482 List* pL = pIT->getAs<List>();
483 const int size = pL->getSize();
484 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
485 for (int i = 0; i < size; ++i)
487 InternalType* pNew = pL->get(i);
489 if (ctx->isprotected(var))
491 std::wostringstream os;
492 os << _W("Redefining permanent variable.\n");
493 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
499 e.getBody().accept(*this);
501 catch (ScilabMessage& sm)
510 if (e.getBody().isBreak())
512 const_cast<Exp*>(&(e.getBody()))->resetBreak();
516 if (e.getBody().isContinue())
518 const_cast<Exp*>(&(e.getBody()))->resetContinue();
522 if (e.getBody().isReturn())
524 const_cast<ForExp*>(&e)->setReturn();
525 const_cast<Exp&>(e.getBody()).resetReturn();
530 else if (pIT->isGenericType())
532 //Matrix i = [1,3,2,6] or other type
533 GenericType* pVar = pIT->getAs<GenericType>();
534 if (pVar->getDims() > 2)
538 throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
541 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
542 for (int i = 0; i < pVar->getCols(); i++)
544 GenericType* pNew = pVar->getColumnValues(i);
549 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
552 if (ctx->isprotected(var))
554 std::wostringstream os;
555 os << _W("Redefining permanent variable.\n");
556 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
562 e.getBody().accept(*this);
564 catch (ScilabMessage& sm)
573 if (e.getBody().isBreak())
575 const_cast<Exp*>(&(e.getBody()))->resetBreak();
579 if (e.getBody().isContinue())
581 const_cast<Exp*>(&(e.getBody()))->resetContinue();
585 if (e.getBody().isReturn())
587 const_cast<ForExp*>(&e)->setReturn();
588 const_cast<Exp&>(e.getBody()).resetReturn();
597 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
607 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
611 if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
614 ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
615 if (pThreadId == NULL)
617 //no paused thread, so just go leave
621 //force exit without prompt of current thread ( via Aborted status )
622 ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
623 pMe->setStatus(ThreadId::Aborted);
625 //resume previous execution thread
632 const_cast<ReturnExp*>(&e)->setReturn();
639 //in case of CallExp, we can return only one values
640 int iSaveExpectedSize = getExpectedSize();
642 e.getExp().accept(*this);
643 setExpectedSize(iSaveExpectedSize);
644 const_cast<ReturnExp*>(&e)->setReturn();
649 void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
652 //e.getSelect()->accept(*this);
653 //InternalType* pIT = getResult();
654 //setResult(nullptr);
655 //if (pIT && pIT->isDouble())
657 // Double * pDbl = static_cast<Double *>(pIT);
658 // if (!pDbl->isComplex() && pDbl->getSize() == 1)
661 // if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
663 // Exp * exp = e.getExp(val);
667 // Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
668 // if (e.isBreakable())
670 // const_cast<IntSelectExp*>(&e)->resetBreak();
671 // body->setBreakable();
674 // if (e.isContinuable())
676 // const_cast<IntSelectExp*>(&e)->resetContinue();
677 // body->setContinuable();
680 // if (e.isReturnable())
682 // const_cast<IntSelectExp*>(&e)->resetReturn();
683 // body->setReturnable();
689 // body->accept(*this);
691 // catch (ScilabMessage& sm)
697 // if (e.isBreakable() && body->isBreak())
699 // const_cast<IntSelectExp*>(&e)->setBreak();
700 // body->resetBreak();
703 // if (e.isContinuable() && body->isContinue())
705 // const_cast<IntSelectExp*>(&e)->setContinue();
706 // body->resetContinue();
709 // if (e.isReturnable() && body->isReturn())
711 // const_cast<IntSelectExp*>(&e)->setReturn();
712 // body->resetReturn();
721 e.getOriginal()->accept(*this);
726 void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
728 e.getSelect()->accept(*this);
729 InternalType* pIT = getResult();
732 if (pIT && pIT->isString())
734 String * pStr = static_cast<String *>(pIT);
735 if (pStr->getSize() == 1)
737 if (wchar_t * s = pStr->get(0))
739 const std::wstring ws(s);
740 Exp * exp = e.getExp(ws);
744 Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
747 const_cast<StringSelectExp*>(&e)->resetBreak();
748 body->setBreakable();
751 if (e.isContinuable())
753 const_cast<StringSelectExp*>(&e)->resetContinue();
754 body->setContinuable();
757 if (e.isReturnable())
759 const_cast<StringSelectExp*>(&e)->resetReturn();
760 body->setReturnable();
768 catch (ScilabMessage& sm)
774 if (e.isBreakable() && body->isBreak())
776 const_cast<StringSelectExp*>(&e)->setBreak();
780 if (e.isContinuable() && body->isContinue())
782 const_cast<StringSelectExp*>(&e)->setContinue();
783 body->resetContinue();
786 if (e.isReturnable() && body->isReturn())
788 const_cast<StringSelectExp*>(&e)->setReturn();
798 e.getOriginal()->accept(*this);
803 void RunVisitorT<T>::visitprivate(const SelectExp &e)
805 // FIXME : exec select ... case ... else ... end
806 e.getSelect()->accept(*this);
809 InternalType* pIT = getResult();
814 exps_t cases = e.getCases();
815 for (auto exp : cases)
817 CaseExp* pCase = exp->getAs<CaseExp>();
818 pCase->getTest()->accept(*this);
819 InternalType *pITCase = getResult();
823 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
827 else if (*pITCase == *pIT)
832 pCase->getBody()->accept(*this);
834 catch (ScilabMessage& sm)
840 if (e.isBreakable() && pCase->getBody()->isBreak())
842 const_cast<SelectExp*>(&e)->setBreak();
843 pCase->getBody()->resetBreak();
846 if (e.isContinuable() && pCase->getBody()->isContinue())
848 const_cast<SelectExp*>(&e)->setContinue();
849 pCase->getBody()->resetContinue();
852 if (e.isReturnable() && pCase->getBody()->isReturn())
854 const_cast<SelectExp*>(&e)->setReturn();
855 pCase->getBody()->resetReturn();
868 if (bCase == false && e.getDefaultCase() != NULL)
873 e.getDefaultCase()->accept(*this);
875 catch (ScilabMessage& sm)
881 if (e.isBreakable() && e.getDefaultCase()->isBreak())
883 const_cast<SelectExp*>(&e)->setBreak();
884 e.getDefaultCase()->resetBreak();
887 if (e.isContinuable() && e.getDefaultCase()->isContinue())
889 const_cast<SelectExp*>(&e)->setContinue();
890 e.getDefaultCase()->resetContinue();
893 if (e.isReturnable() && e.getDefaultCase()->isReturn())
895 const_cast<SelectExp*>(&e)->setReturn();
896 e.getDefaultCase()->resetReturn();
906 void RunVisitorT<T>::visitprivate(const SeqExp &e)
908 types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
910 for (auto exp : e.getExps())
912 if (exp->isCommentExp())
917 if (pThreadMe && pThreadMe->getInterrupt())
919 ThreadManagement::SendAstPendingSignal();
920 pThreadMe->suspend();
925 //reset default values
927 int iExpectedSize = getExpectedSize();
930 setExpectedSize(iExpectedSize);
931 InternalType * pIT = getResult();
933 // In case of exec file, set the file name in the Macro to store where it is defined.
934 int iFileID = ConfigVariable::getExecutedFileID();
935 if (iFileID && exp->isFunctionDec())
937 InternalType* pITMacro = symbol::Context::getInstance()->get(exp->getAs<FunctionDec>()->getSymbol());
940 types::Macro* pMacro = pITMacro->getAs<types::Macro>();
941 const wchar_t* filename = getfile_filename(iFileID);
942 // scilab.quit is not open with mopen
943 // in this case filename is NULL because FileManager have not been filled.
946 pMacro->setFileName(filename);
953 bool bImplicitCall = false;
954 if (pIT->isCallable()) //to manage call without ()
956 Callable *pCall = pIT->getAs<Callable>();
963 //in this case of calling, we can return only one values
964 int iSaveExpectedSize = getExpectedSize();
967 pCall->invoke(in, opt, getExpectedSize(), out, *this, e);
968 setExpectedSize(iSaveExpectedSize);
979 bImplicitCall = true;
981 catch (ScilabMessage& sm)
983 if (ConfigVariable::getLastErrorFunction() == L"")
985 ConfigVariable::setLastErrorFunction(pCall->getName());
990 catch (ast::ScilabError & se)
992 if (ConfigVariable::getLastErrorFunction() == L"")
994 ConfigVariable::setLastErrorFunction(pCall->getName());
995 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
1002 //don't output Simplevar and empty result
1003 if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
1005 //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
1006 InternalType* pITAns = getResult();
1007 symbol::Context::getInstance()->put(m_pAns, pITAns);
1008 if (exp->isVerbose() && ConfigVariable::isPromptShow())
1010 //TODO manage multiple returns
1011 scilabWriteW(L" ans =\n\n");
1012 std::wostringstream ostrName;
1014 VariableToString(pITAns, ostrName.str().c_str());
1021 if ((&e)->isBreakable() && exp->isBreak())
1023 const_cast<SeqExp *>(&e)->setBreak();
1028 if ((&e)->isContinuable() && exp->isContinue())
1030 const_cast<SeqExp *>(&e)->setContinue();
1031 exp->resetContinue();
1035 if ((&e)->isReturnable() && exp->isReturn())
1037 const_cast<SeqExp *>(&e)->setReturn();
1042 catch (ScilabMessage& sm)
1044 ConfigVariable::fillWhereError(sm.GetErrorLocation().first_line);
1047 catch (const ScilabError& se)
1049 // check on error number because error message can be empty.
1050 if (ConfigVariable::getLastErrorNumber() == 0)
1052 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
1053 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
1054 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
1055 ConfigVariable::setLastErrorFunction(wstring(L""));
1058 ConfigVariable::fillWhereError(se.GetErrorLocation().first_line);
1059 throw ScilabMessage(se.GetErrorMessage(), se.GetErrorNumber(), se.GetErrorLocation());
1062 // If something other than NULL is given to setResult, then that would imply
1063 // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
1069 void RunVisitorT<T>::visitprivate(const NotExp &e)
1074 e.getExp().accept(*this);
1076 InternalType * pValue = getResult();
1077 InternalType * pReturn = NULL;
1078 if (pValue->neg(pReturn))
1080 if (pValue != pReturn)
1089 // neg returned false so the negation is not possible so we call the overload (%foo_5)
1090 types::typed_list in;
1091 types::typed_list out;
1093 pValue->IncreaseRef();
1094 in.push_back(pValue);
1096 Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
1098 if (Ret != Callable::OK)
1100 cleanInOut(in, out);
1101 throw ScilabError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1110 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
1112 e.getExp().accept(*this);
1114 if (getResultSize() != 1)
1117 wchar_t szError[bsiz];
1118 os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1119 throw ScilabError(szError, 999, e.getLocation());
1122 InternalType * pValue = getResult();
1123 InternalType * pReturn = NULL;
1124 const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1126 if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1128 if (pValue != pReturn)
1139 // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1140 types::typed_list in;
1141 types::typed_list out;
1143 pValue->IncreaseRef();
1144 in.push_back(pValue);
1146 Callable::ReturnValue Ret;
1149 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1153 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1156 if (Ret != Callable::OK)
1158 cleanInOut(in, out);
1159 throw ScilabError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1168 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1170 symbol::Context* ctx = symbol::Context::getInstance();
1176 // funcprot(0) : do nothing
1177 // funcprot(1) && warning(on) : warning
1178 //get input parameters list
1179 std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1180 const exps_t & vars = e.getArgs().getVars();
1181 for (const auto var : vars)
1183 pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1186 //get output parameters list
1187 std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1188 const exps_t & rets = e.getReturns().getVars();
1189 for (const auto ret : rets)
1191 pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1194 types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1195 const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1196 pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
1198 bool bEquals = false;
1199 int iFuncProt = ConfigVariable::getFuncprot();
1202 types::InternalType* pITFunc = ctx->get(((FunctionDec&)e).getStack());
1203 if (pITFunc && pITFunc->isCallable())
1205 if (pITFunc->isMacroFile())
1207 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1208 bEquals = *pMF->getMacro() == *pMacro;
1210 else if (pITFunc->isMacro())
1212 types::Macro* pM = pITFunc->getAs<types::Macro>();
1213 bEquals = *pM == *pMacro;
1218 bEquals = true; //avoid msg but keep assignation
1222 if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1224 wchar_t pwstFuncName[1024];
1225 os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1226 char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1229 sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1233 else if (bEquals == false && iFuncProt == 2)
1235 char pstError[1024];
1236 char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1237 os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1238 wchar_t* pwstError = to_wide_string(pstError);
1239 std::wstring wstError(pwstError);
1243 throw ScilabError(wstError, 999, e.getLocation());
1247 if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1250 std::wostringstream os;
1251 os << _W("Redefining permanent variable.\n");
1252 throw ScilabError(os.str(), 999, e.getLocation());
1255 ctx->addMacro(pMacro);
1260 void RunVisitorT<T>::visitprivate(const ListExp &e)
1262 e.getStart().accept(*this);
1263 GenericType* pITStart = static_cast<GenericType*>(getResult());
1264 if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1265 pITStart->isList() == false) // list case => call overload
1268 wchar_t szError[bsiz];
1269 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1270 throw ScilabError(szError, 999, e.getLocation());
1272 InternalType * piStart = pITStart;
1274 e.getStep().accept(*this);
1275 GenericType* pITStep = static_cast<GenericType*>(getResult());
1276 if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1277 pITStep->isList() == false) // list case => call overload
1281 wchar_t szError[bsiz];
1282 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1283 throw ScilabError(szError, 999, e.getLocation());
1285 InternalType* piStep = pITStep;
1287 e.getEnd().accept(*this);
1288 GenericType* pITEnd = static_cast<GenericType*>(getResult());
1289 if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1290 pITEnd->isList() == false) // list case => call overload
1295 wchar_t szError[bsiz];
1296 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1297 throw ScilabError(szError, 999, e.getLocation());
1299 InternalType* piEnd = pITEnd;
1301 ////check if implicitlist is 1:$ to replace by ':'
1302 //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1304 // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1306 // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1307 // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1309 // setResult(new Colon());
1315 //check compatibility
1316 // double : double : double or poly : poly : poly and mix like double : double : poly
1317 if ((piStart->isPoly() || piStart->isDouble()) &&
1318 (piStep->isPoly() || piStep->isDouble()) &&
1319 (piEnd->isPoly() || piEnd->isDouble()))
1321 // No need to kill piStart, ... because Implicit list ctor will incref them
1322 setResult(new ImplicitList(piStart, piStep, piEnd));
1326 // int : double or int : int
1327 if ( piStart->isInt() &&
1328 (piStep->isDouble() || piStep->isInt()) &&
1331 // check for same int type int8, int 16 ...
1332 if (piStart->getType() == piEnd->getType() &&
1333 (piStart->getType() == piStep->getType() ||
1334 piStep->isDouble()))
1336 // No need to kill piStart, ... because Implicit list ctor will incref them
1337 setResult(new ImplicitList(piStart, piStep, piEnd));
1343 Callable::ReturnValue Ret;
1344 types::typed_list in;
1345 types::typed_list out;
1347 piStart->IncreaseRef();
1348 in.push_back(piStart);
1352 if (e.hasExplicitStep())
1355 //call overload %typeStart_b_typeStep
1356 piStep->IncreaseRef();
1357 in.push_back(piStep);
1358 piEnd->IncreaseRef();
1359 in.push_back(piEnd);
1360 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1365 //call overload %typeStart_b_typeEnd
1367 piEnd->IncreaseRef();
1368 in.push_back(piEnd);
1369 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1372 catch (ScilabError& error)
1374 cleanInOut(in, out);
1377 catch (ast::ScilabMessage msg)
1379 cleanInOut(in, out);
1383 if (Ret != Callable::OK)
1385 cleanInOut(in, out);
1386 throw ScilabError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
1394 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1399 void RunVisitorT<T>::visitprivate(const MemfillExp &e)
1401 e.getOriginal()->accept(*this);
1405 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1407 InternalType* pIT = NULL;
1420 //check types and dimensions
1423 const Exp &ye = e.getY();
1426 if (pIT->isDouble())
1428 yd = pIT->getAs<Double>();
1429 if (yd->getDims() == 2 && yd->isComplex() == false)
1437 e.getOriginal()->accept(*this);
1444 e.getOriginal()->accept(*this);
1449 const Exp &xe = e.getX();
1453 if (pIT->isDouble())
1455 xd = pIT->getAs<Double>();
1456 if (xd->isScalar() && xd->isComplex() == false)
1463 else if (xd->getDims() == 2 && xd->isComplex() == false)
1472 e.getOriginal()->accept(*this);
1480 e.getOriginal()->accept(*this);
1484 const Exp &ae = e.getA();
1488 if (pIT->isDouble())
1492 xd = pIT->getAs<Double>();
1493 //X is scalar it become A
1495 if (xd->getDims() == 2 && xd->isComplex() == false)
1505 e.getOriginal()->accept(*this);
1511 //a is a and it must be scalar
1512 ad = pIT->getAs<Double>();
1513 if (/*ad->isScalar() && */ad->isComplex() == false)
1515 ar = ad->getRows(); //1;
1516 ac = ad->getCols();//1;
1523 e.getOriginal()->accept(*this);
1533 e.getOriginal()->accept(*this);
1547 //Double* od = (Double*)yd->clone();
1548 C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1555 else if (ac == xr && ar == yr && xc == yc)
1559 C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1581 e.getOriginal()->accept(*this);
1585 } /* namespace ast */
1587 #include "run_CallExp.hpp"
1588 #include "run_MatrixExp.hpp"
1589 #include "run_OpExp.hpp"
1590 #include "run_AssignExp.hpp"
1592 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1593 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1594 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;