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"
28 #include "visitor_common.hxx"
30 #include "context.hxx"
31 #include "generic_operations.hxx"
32 #include "types_or.hxx"
33 #include "types_and.hxx"
34 #include "localization.hxx"
36 #include "macrofile.hxx"
40 #include "threadmanagement.hxx"
45 #include "os_string.h"
46 #include "elem_common.h"
52 void RunVisitorT<T>::visitprivate(const CellExp &e)
54 exps_t::const_iterator row;
55 exps_t::const_iterator col;
58 exps_t lines = e.getLines();
60 for (row = lines.begin() ; row != lines.end() ; ++row )
62 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
65 iColMax = static_cast<int>(cols.size());
68 if (iColMax != static_cast<int>(cols.size()))
70 std::wostringstream os;
71 os << _W("inconsistent row/column dimensions\n");
72 //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
73 throw ScilabError(os.str(), 999, (*row)->getLocation());
78 types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
83 //insert items in cell
84 for (i = 0, row = lines.begin() ; row != lines.end() ; ++row, ++i)
86 exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
87 for (j = 0, col = cols.begin() ; col != cols.end() ; ++col, ++j)
89 (*col)->accept(*this);
90 InternalType *pIT = getResult();
91 if (pIT->isImplicitList())
93 InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
110 void RunVisitorT<T>::visitprivate(const FieldExp &e)
116 if (!e.getTail()->isSimpleVar())
118 wchar_t szError[bsiz];
119 os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
120 throw ScilabError(szError, 999, e.getLocation());
125 e.getHead()->accept(*this);
127 catch (const ScilabError& error)
132 if (getResult() == NULL)
134 wchar_t szError[bsiz];
135 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
136 throw ScilabError(szError, 999, e.getLocation());
139 // TODO: handle case where getSize() > 1
140 // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
142 if (getResultSize() > 1)
145 wchar_t szError[bsiz];
146 os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
147 throw ScilabError(szError, 999, e.getLocation());
150 SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
151 std::wstring wstField = psvRightMember->getSymbol().getName();
152 InternalType * pValue = getResult();
153 InternalType * pReturn = NULL;
158 if (pValue->isGenericType())
160 ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
163 catch (std::wstring & err)
166 throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
173 std::wostringstream os;
174 os << _W("Invalid index.\n");
175 throw ScilabError(os.str(), 999, e.getLocation());
179 if (pValue->isDeletable())
181 if (pValue->isContainer())
183 // prevent delete of pReturn in case where
184 // extract not return a clone
185 pReturn->IncreaseRef();
187 pReturn->DecreaseRef();
195 else if (pValue->isFieldExtractionOverloadable())
197 types::typed_list in;
198 types::typed_list out;
200 String* pS = new String(wstField.c_str());
202 //TODO: in the case where overload is a macro there is no need to incref in
203 // because args will be put in context, removed and killed if required.
204 // But if the overload is a function... it is another story...
207 pValue->IncreaseRef();
210 in.push_back(pValue);
211 Callable::ReturnValue Ret = Callable::Error;
212 std::wstring stType = pValue->getShortTypeStr();
216 Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
218 catch (ast::ScilabError & se)
222 //to compatibility with scilab 5 code.
223 //tlist/mlist name are truncated to 8 first character
224 if (stType.size() > 8)
226 Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, this);
233 catch (ast::ScilabError & se)
236 if (pValue->isList())
238 Ret = Overload::call(L"%l_e", in, 1, out, this);
247 if (Ret != Callable::OK)
259 wchar_t szError[bsiz];
260 os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
261 throw ScilabError(szError, 999, e.getLocation());
266 void RunVisitorT<T>::visitprivate(const IfExp &e)
268 //Create local exec visitor
269 ShortCutVisitor SCTest;
270 bool bTestStatus = false;
273 e.getTest().accept(SCTest);
274 e.getTest().accept(*this);
276 bTestStatus = getResult()->isTrue();
278 if (bTestStatus == true)
280 e.getThen().accept(*this);
282 else if (e.hasElse())
284 e.getElse().accept(*this);
288 && ( (&e.getElse())->isBreak()
289 || (&e.getThen())->isBreak() ))
291 const_cast<IfExp*>(&e)->setBreak();
292 const_cast<Exp*>(&e.getElse())->resetBreak();
293 const_cast<Exp*>(&e.getThen())->resetBreak();
296 if (e.isContinuable()
297 && ( (&e.getElse())->isContinue()
298 || (&e.getThen())->isContinue() ))
300 const_cast<IfExp*>(&e)->setContinue();
301 const_cast<Exp*>(&e.getElse())->resetContinue();
302 const_cast<Exp*>(&e.getThen())->resetContinue();
306 && ( (&e.getElse())->isReturn()
307 || (&e.getThen())->isReturn() ))
309 const_cast<IfExp*>(&e)->setReturn();
310 const_cast<Exp*>(&e.getElse())->resetReturn();
311 const_cast<Exp*>(&e.getThen())->resetReturn();
316 void RunVisitorT<T>::visitprivate(const WhileExp &e)
319 e.getTest().accept(*this);
320 InternalType* pIT = getResult();
321 while (pIT->isTrue())
324 e.getBody().accept(*this);
326 //clear old result value before evaluate new one
327 if (getResult() != NULL)
329 getResult()->killMe();
332 if (e.getBody().isBreak())
334 const_cast<Exp*>(&(e.getBody()))->resetBreak();
338 if (e.getBody().isReturn())
340 const_cast<WhileExp*>(&e)->setReturn();
341 const_cast<Exp*>(&(e.getBody()))->resetReturn();
345 if (e.getBody().isContinue())
347 const_cast<Exp*>(&(e.getBody()))->resetContinue();
350 e.getTest().accept(*this);
355 //clear result of condition or result of body
360 void RunVisitorT<T>::visitprivate(const ForExp &e)
362 symbol::Context* ctx = symbol::Context::getInstance();
363 //vardec visit increase its result reference
364 e.getVardec().accept(*this);
365 InternalType* pIT = getResult();
367 if (pIT->isImplicitList())
370 ImplicitList* pVar = pIT->getAs<ImplicitList>();
371 //get IL initial Type
372 InternalType * pIL = pVar->getInitalType();
373 //std::cout << "for IL: " << pIL << std::endl;
374 //std::cout << " for IV: " << pIT << std::endl;
376 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
378 if (ctx->isprotected(var))
380 std::wostringstream os;
381 os << _W("Redefining permanent variable.\n");
382 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
386 //use ref count to lock var against clear and detect any changes
389 int size = pVar->getSize();
390 for (int i = 0; i < size; ++i)
392 //check if loop index has changed, deleted, copy ...
393 if (pIL->getRef() != 2)
395 switch (pIL->getRef())
402 //someone assign me to another var
408 pIL = pVar->getInitalType();
411 //update me ( must decrease ref of a )
412 if (ctx->isprotected(var))
414 std::wostringstream os;
415 os << _W("Redefining permanent variable.\n");
416 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
424 pVar->extractValue(i, pIL);
426 bool clearAndExit = false;
429 e.getBody().accept(*this);
431 catch (ScilabMessage& sm)
433 //unlock loop index and implicit list
443 if (e.getBody().isBreak())
445 const_cast<Exp&>(e.getBody()).resetBreak();
449 if (e.getBody().isContinue())
451 const_cast<Exp&>(e.getBody()).resetContinue();
455 if (e.getBody().isReturn())
457 const_cast<ForExp&>(e).setReturn();
458 const_cast<Exp&>(e.getBody()).resetReturn();
467 else if (pIT->isList())
469 List* pL = pIT->getAs<List>();
470 const int size = pL->getSize();
471 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
472 for (int i = 0; i < size; ++i)
474 InternalType* pNew = pL->get(i);
476 if (ctx->isprotected(var))
478 std::wostringstream os;
479 os << _W("Redefining permanent variable.\n");
480 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
486 e.getBody().accept(*this);
488 catch (ScilabMessage& sm)
497 if (e.getBody().isBreak())
499 const_cast<Exp*>(&(e.getBody()))->resetBreak();
503 if (e.getBody().isContinue())
505 const_cast<Exp*>(&(e.getBody()))->resetContinue();
509 if (e.getBody().isReturn())
511 const_cast<ForExp*>(&e)->setReturn();
512 const_cast<Exp&>(e.getBody()).resetReturn();
517 else if (pIT->isGenericType())
519 //Matrix i = [1,3,2,6] or other type
520 GenericType* pVar = pIT->getAs<GenericType>();
521 if (pVar->getDims() > 2)
525 throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
528 symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
529 for (int i = 0; i < pVar->getCols(); i++)
531 GenericType* pNew = pVar->getColumnValues(i);
536 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
539 if (ctx->isprotected(var))
541 std::wostringstream os;
542 os << _W("Redefining permanent variable.\n");
543 throw ast::ScilabError(os.str(), 999, e.getVardec().getLocation());
549 e.getBody().accept(*this);
551 catch (ScilabMessage& sm)
560 if (e.getBody().isBreak())
562 const_cast<Exp*>(&(e.getBody()))->resetBreak();
566 if (e.getBody().isContinue())
568 const_cast<Exp*>(&(e.getBody()))->resetContinue();
572 if (e.getBody().isReturn())
574 const_cast<ForExp*>(&e)->setReturn();
575 const_cast<Exp&>(e.getBody()).resetReturn();
584 throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
594 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
598 if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
601 ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
602 if (pThreadId == NULL)
604 //no paused thread, so just go leave
608 //force exit without prompt of current thread ( via Aborted status )
609 ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
610 pMe->setStatus(ThreadId::Aborted);
612 //resume previous execution thread
619 const_cast<ReturnExp*>(&e)->setReturn();
626 //in case of CallExp, we can return only one values
627 int iSaveExpectedSize = getExpectedSize();
629 e.getExp().accept(*this);
630 setExpectedSize(iSaveExpectedSize);
631 const_cast<ReturnExp*>(&e)->setReturn();
636 void RunVisitorT<T>::visitprivate(const SelectExp &e)
638 // FIXME : exec select ... case ... else ... end
639 e.getSelect()->accept(*this);
642 InternalType* pIT = getResult();
647 exps_t cases = e.getCases();
648 for (auto exp : cases)
650 CaseExp* pCase = exp->getAs<CaseExp>();
651 pCase->getTest()->accept(*this);
652 InternalType *pITCase = getResult();
656 if (pITCase->isContainer()) //WARNING ONLY FOR CELL
660 else if (*pITCase == *pIT)
665 pCase->getBody()->accept(*this);
667 catch (ScilabMessage& sm)
673 if (e.isBreakable() && pCase->getBody()->isBreak())
675 const_cast<SelectExp*>(&e)->setBreak();
676 pCase->getBody()->resetBreak();
679 if (e.isContinuable() && pCase->getBody()->isContinue())
681 const_cast<SelectExp*>(&e)->setContinue();
682 pCase->getBody()->resetContinue();
685 if (e.isReturnable() && pCase->getBody()->isReturn())
687 const_cast<SelectExp*>(&e)->setReturn();
688 pCase->getBody()->resetReturn();
701 if (bCase == false && e.getDefaultCase() != NULL)
706 e.getDefaultCase()->accept(*this);
708 catch (ScilabMessage& sm)
714 if (e.isBreakable() && e.getDefaultCase()->isBreak())
716 const_cast<SelectExp*>(&e)->setBreak();
717 e.getDefaultCase()->resetBreak();
720 if (e.isContinuable() && e.getDefaultCase()->isContinue())
722 const_cast<SelectExp*>(&e)->setContinue();
723 e.getDefaultCase()->resetContinue();
726 if (e.isReturnable() && e.getDefaultCase()->isReturn())
728 const_cast<SelectExp*>(&e)->setReturn();
729 e.getDefaultCase()->resetReturn();
739 void RunVisitorT<T>::visitprivate(const SeqExp &e)
741 types::ThreadId* pThreadMe = ConfigVariable::getThread(__GetCurrentThreadKey());
743 for (auto exp : e.getExps())
745 if (exp->isCommentExp())
750 if (pThreadMe && pThreadMe->getInterrupt())
752 ThreadManagement::SendAstPendingSignal();
753 pThreadMe->suspend();
758 //reset default values
760 int iExpectedSize = getExpectedSize();
763 setExpectedSize(iExpectedSize);
764 InternalType * pIT = getResult();
768 bool bImplicitCall = false;
769 if (pIT->isCallable()) //to manage call without ()
771 Callable *pCall = pIT->getAs<Callable>();
778 //in this case of calling, we can return only one values
779 int iSaveExpectedSize = getExpectedSize();
782 pCall->invoke(in, opt, getExpectedSize(), out, *this, e);
783 setExpectedSize(iSaveExpectedSize);
794 bImplicitCall = true;
796 catch (ScilabMessage& sm)
799 PrintVisitor printMe(os);
800 exp->accept(printMe);
801 //os << std::endl << std::endl;
802 if (ConfigVariable::getLastErrorFunction() == L"")
804 ConfigVariable::setLastErrorFunction(pCall->getName());
807 if (pCall->isMacro() || pCall->isMacroFile())
809 wchar_t szError[bsiz];
810 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
811 throw ScilabMessage(szError + os.str());
815 sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
819 catch (ast::ScilabError & se)
821 if (ConfigVariable::getLastErrorFunction() == L"")
823 ConfigVariable::setLastErrorFunction(pCall->getName());
824 ConfigVariable::setLastErrorLine(e.getLocation().first_line);
828 if (pCall->isMacro() || pCall->isMacroFile())
830 wchar_t szError[bsiz];
831 os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), exp->getLocation().first_line, pCall->getName().c_str());
832 throw ScilabMessage(szError);
836 throw ScilabMessage();
841 //don't output Simplevar and empty result
842 if (getResult() != NULL && (!exp->isSimpleVar() || bImplicitCall))
844 //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
845 InternalType* pITAns = getResult();
846 symbol::Context::getInstance()->put(m_pAns, pITAns);
847 if (exp->isVerbose() && ConfigVariable::isPromptShow())
849 //TODO manage multiple returns
850 scilabWriteW(L" ans =\n\n");
851 std::wostringstream ostrName;
853 VariableToString(pITAns, ostrName.str().c_str());
860 if ((&e)->isBreakable() && exp->isBreak())
862 const_cast<SeqExp *>(&e)->setBreak();
867 if ((&e)->isContinuable() && exp->isContinue())
869 const_cast<SeqExp *>(&e)->setContinue();
870 exp->resetContinue();
874 if ((&e)->isReturnable() && exp->isReturn())
876 const_cast<SeqExp *>(&e)->setReturn();
881 catch (const ScilabMessage& sm)
883 scilabErrorW(sm.GetErrorMessage().c_str());
885 CallExp* pCall = dynamic_cast<CallExp*>(exp);
888 //to print call expression only of it is a macro
889 pCall->getName().accept(*this);
891 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
894 PrintVisitor printMe(os);
895 pCall->accept(printMe);
896 //os << std::endl << std::endl;
897 if (ConfigVariable::getLastErrorFunction() == L"")
899 ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
901 throw ScilabMessage(os.str(), 0, exp->getLocation());
904 throw ScilabMessage(exp->getLocation());
906 catch (const ScilabError& se)
908 // check on error number because error message can be empty.
909 if (ConfigVariable::getLastErrorNumber() == 0)
911 ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
912 ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
913 ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
914 ConfigVariable::setLastErrorFunction(wstring(L""));
917 CallExp* pCall = dynamic_cast<CallExp*>(exp);
920 //to print call expression only of it is a macro
923 pCall->getName().accept(*this);
924 if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
927 PrintVisitor printMe(os);
928 pCall->accept(printMe);
929 //os << std::endl << std::endl;
930 ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
931 scilabErrorW(se.GetErrorMessage().c_str());
932 throw ScilabMessage(os.str(), 999, exp->getLocation());
935 catch (ScilabError& se2)
937 //just to catch exception, do nothing
941 scilabErrorW(se.GetErrorMessage().c_str());
943 throw ScilabMessage(exp->getLocation());
946 // If something other than NULL is given to setResult, then that would imply
947 // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
953 void RunVisitorT<T>::visitprivate(const NotExp &e)
958 e.getExp().accept(*this);
960 InternalType * pValue = getResult();
961 InternalType * pReturn = NULL;
962 if (pValue->neg(pReturn))
964 if (pValue != pReturn)
973 // neg returned false so the negation is not possible so we call the overload (%foo_5)
974 types::typed_list in;
975 types::typed_list out;
977 pValue->IncreaseRef();
978 in.push_back(pValue);
980 Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
982 if (Ret != Callable::OK)
994 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
996 e.getExp().accept(*this);
998 if (getResultSize() != 1)
1001 wchar_t szError[bsiz];
1002 os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
1003 throw ScilabError(szError, 999, e.getLocation());
1006 InternalType * pValue = getResult();
1007 InternalType * pReturn = NULL;
1008 const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
1010 if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
1012 if (pValue != pReturn)
1023 // transpose returned false so the negation is not possible so we call the overload (%foo_t or %foo_0)
1024 types::typed_list in;
1025 types::typed_list out;
1027 pValue->IncreaseRef();
1028 in.push_back(pValue);
1030 Callable::ReturnValue Ret;
1033 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
1037 Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
1040 if (Ret != Callable::OK)
1042 cleanInOut(in, out);
1043 throw ScilabError();
1052 void RunVisitorT<T>::visitprivate(const FunctionDec & e)
1054 symbol::Context* ctx = symbol::Context::getInstance();
1060 // funcprot(0) : do nothing
1061 // funcprot(1) && warning(on) : warning
1062 //get input parameters list
1063 std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
1064 const exps_t & vars = e.getArgs().getVars();
1065 for (const auto var : vars)
1067 pVarList->push_back(var->getAs<SimpleVar>()->getStack());
1070 //get output parameters list
1071 std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
1072 const exps_t & rets = e.getReturns().getVars();
1073 for (const auto ret : rets)
1075 pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
1078 types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
1079 const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
1080 pMacro->setFirstLine(e.getLocation().first_line);
1082 bool bEquals = false;
1083 int iFuncProt = ConfigVariable::getFuncprot();
1086 types::InternalType* pITFunc = ctx->get(((FunctionDec&)e).getStack());
1087 if (pITFunc && pITFunc->isCallable())
1089 if (pITFunc->isMacroFile())
1091 types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
1092 bEquals = *pMF->getMacro() == *pMacro;
1094 else if (pITFunc->isMacro())
1096 types::Macro* pM = pITFunc->getAs<types::Macro>();
1097 bEquals = *pM == *pMacro;
1102 bEquals = true; //avoid msg but keep assignation
1106 if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
1108 wchar_t pwstFuncName[1024];
1109 os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
1110 char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
1113 sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
1117 else if (bEquals == false && iFuncProt == 2)
1119 char pstError[1024];
1120 char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
1121 os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
1122 wchar_t* pwstError = to_wide_string(pstError);
1123 std::wstring wstError(pwstError);
1127 throw ScilabError(wstError, 999, e.getLocation());
1131 if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
1134 std::wostringstream os;
1135 os << _W("Redefining permanent variable.\n");
1136 throw ScilabError(os.str(), 999, e.getLocation());
1139 ctx->addMacro(pMacro);
1144 void RunVisitorT<T>::visitprivate(const ListExp &e)
1146 e.getStart().accept(*this);
1147 GenericType* pITStart = static_cast<GenericType*>(getResult());
1148 if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
1149 pITStart->isList() == false) // list case => call overload
1152 wchar_t szError[bsiz];
1153 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
1154 throw ScilabError(szError, 999, e.getLocation());
1156 InternalType * piStart = pITStart;
1158 e.getStep().accept(*this);
1159 GenericType* pITStep = static_cast<GenericType*>(getResult());
1160 if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
1161 pITStep->isList() == false) // list case => call overload
1165 wchar_t szError[bsiz];
1166 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
1167 throw ScilabError(szError, 999, e.getLocation());
1169 InternalType* piStep = pITStep;
1171 e.getEnd().accept(*this);
1172 GenericType* pITEnd = static_cast<GenericType*>(getResult());
1173 if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
1174 pITEnd->isList() == false) // list case => call overload
1179 wchar_t szError[bsiz];
1180 os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
1181 throw ScilabError(szError, 999, e.getLocation());
1183 InternalType* piEnd = pITEnd;
1185 ////check if implicitlist is 1:$ to replace by ':'
1186 //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
1188 // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
1190 // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
1191 // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
1193 // setResult(new Colon());
1199 //check compatibility
1200 // double : double : double or poly : poly : poly and mix like double : double : poly
1201 if ((piStart->isPoly() || piStart->isDouble()) &&
1202 (piStep->isPoly() || piStep->isDouble()) &&
1203 (piEnd->isPoly() || piEnd->isDouble()))
1205 // No need to kill piStart, ... because Implicit list ctor will incref them
1206 setResult(new ImplicitList(piStart, piStep, piEnd));
1210 // int : double or int : int
1211 if ( piStart->isInt() &&
1212 (piStep->isDouble() || piStep->isInt()) &&
1215 // check for same int type int8, int 16 ...
1216 if (piStart->getType() == piEnd->getType() &&
1217 (piStart->getType() == piStep->getType() ||
1218 piStep->isDouble()))
1220 // No need to kill piStart, ... because Implicit list ctor will incref them
1221 setResult(new ImplicitList(piStart, piStep, piEnd));
1227 Callable::ReturnValue Ret;
1228 types::typed_list in;
1229 types::typed_list out;
1231 piStart->IncreaseRef();
1232 in.push_back(piStart);
1236 if (e.hasExplicitStep())
1239 //call overload %typeStart_b_typeStep
1240 piStep->IncreaseRef();
1241 in.push_back(piStep);
1242 piEnd->IncreaseRef();
1243 in.push_back(piEnd);
1244 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
1249 //call overload %typeStart_b_typeEnd
1251 piEnd->IncreaseRef();
1252 in.push_back(piEnd);
1253 Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
1256 catch (ScilabError& error)
1258 cleanInOut(in, out);
1261 catch (ast::ScilabMessage msg)
1263 cleanInOut(in, out);
1267 if (Ret != Callable::OK)
1269 cleanInOut(in, out);
1270 throw ScilabError();
1278 void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
1283 void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
1285 InternalType* pIT = NULL;
1298 //check types and dimensions
1301 const Exp &ye = e.getY();
1304 if (pIT->isDouble())
1306 yd = pIT->getAs<Double>();
1307 if (yd->getDims() == 2 && yd->isComplex() == false)
1315 e.getOriginal()->accept(*this);
1322 e.getOriginal()->accept(*this);
1327 const Exp &xe = e.getX();
1331 if (pIT->isDouble())
1333 xd = pIT->getAs<Double>();
1334 if (xd->isScalar() && xd->isComplex() == false)
1341 else if (xd->getDims() == 2 && xd->isComplex() == false)
1350 e.getOriginal()->accept(*this);
1358 e.getOriginal()->accept(*this);
1362 const Exp &ae = e.getA();
1366 if (pIT->isDouble())
1370 xd = pIT->getAs<Double>();
1371 //X is scalar it become A
1373 if (xd->getDims() == 2 && xd->isComplex() == false)
1383 e.getOriginal()->accept(*this);
1389 //a is a and it must be scalar
1390 ad = pIT->getAs<Double>();
1391 if (/*ad->isScalar() && */ad->isComplex() == false)
1393 ar = ad->getRows(); //1;
1394 ac = ad->getCols();//1;
1401 e.getOriginal()->accept(*this);
1411 e.getOriginal()->accept(*this);
1425 //Double* od = (Double*)yd->clone();
1426 C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
1433 else if (ac == xr && ar == yr && xc == yc)
1437 C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
1459 e.getOriginal()->accept(*this);
1463 } /* namespace ast */
1465 #include "run_CallExp.hpp"
1466 #include "run_MatrixExp.hpp"
1467 #include "run_OpExp.hpp"
1468 #include "run_AssignExp.hpp"
1470 template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
1471 template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
1472 template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;