* Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
* Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
*
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
*
*/
+//for Visual Leak Detector in debug compilation mode
+//#define DEBUG_VLD
+#if defined(DEBUG_VLD) && defined(_DEBUG)
+#include <vld.h>
+#endif
+
#include <string>
-#include "runvisitor.hxx"
#include "execvisitor.hxx"
#include "stepvisitor.hxx"
#include "timedvisitor.hxx"
#include "shortcutvisitor.hxx"
#include "printvisitor.hxx"
-#include "mutevisitor.hxx"
+//#include "AnalysisVisitor.hxx"
+#include "debuggervisitor.hxx"
+#include "debugmanager.hxx"
#include "visitor_common.hxx"
#include "macrofile.hxx"
#include "macro.hxx"
+#include "cell.hxx"
+#include "listinsert.hxx"
+#include "filemanager_interface.h"
+
+#include "runner.hxx"
+#include "threadmanagement.hxx"
+
+#include "coverage_instance.hxx"
extern "C"
{
#include "sciprint.h"
-#include "os_swprintf.h"
+#include "os_string.h"
+#include "elem_common.h"
+#include "storeCommand.h"
+#include "prompt.h"
+#include "scilabRead.h"
}
namespace ast
{
template <class T>
-void RunVisitorT<T>::visitprivate(const CellExp &e)
+void RunVisitorT<T>::visitprivate(const StringExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ if (e.getConstant() == nullptr)
+ {
+ types::String *psz = new types::String(e.getValue().c_str());
+ (const_cast<StringExp *>(&e))->setConstant(psz);
+ }
+ setResult(e.getConstant());
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const DoubleExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ if (e.getConstant() == nullptr)
+ {
+ types::Double *pdbl = new types::Double(e.getValue());
+ (const_cast<DoubleExp *>(&e))->setConstant(pdbl);
+ }
+ setResult(e.getConstant());
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const BoolExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ if (e.getConstant() == nullptr)
+ {
+ types::Bool *pB = new types::Bool(e.getValue());
+ (const_cast<BoolExp *>(&e))->setConstant(pB);
+ }
+ setResult(e.getConstant());
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const NilExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ setResult(new types::Void());
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const SimpleVar & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ symbol::Context* ctx = symbol::Context::getInstance();
+ symbol::Variable* var = ((SimpleVar&)e).getStack();
+ types::InternalType *pI = ctx->get(var);
+ setResult(pI);
+ if (pI != nullptr)
+ {
+ if (e.isVerbose() && pI->isCallable() == false && ConfigVariable::isPrintOutput())
+ {
+ std::wostringstream ostr;
+ ostr << L" " << e.getSymbol().getName() << L" = ";
+#ifndef NDEBUG
+ ostr << L"(" << pI->getRef() << L")";
+#endif
+ ostr << std::endl;
+ if (ConfigVariable::isPrintCompact() == false)
+ {
+ ostr << std::endl;
+ }
+ scilabWriteW(ostr.str().c_str());
+ std::wostringstream ostrName;
+ ostrName << e.getSymbol().getName();
+ VariableToString(pI, ostrName.str().c_str());
+ }
+
+ //check if var is recalled in current scope like
+ //function f()
+ // a; //<=> a=a;
+ // a(2) = 18;
+ //endfunction
+ if (e.getParent()->isSeqExp())
+ {
+ if (ctx->getScopeLevel() > 1 && var->empty() == false && var->top()->m_iLevel != ctx->getScopeLevel())
+ {
+ //put var in current scope
+ ctx->put(var, pI);
+ }
+ }
+ }
+ else
+ {
+ char pstError[bsiz];
+ wchar_t* pwstError;
+
+ char* strErr = wide_string_to_UTF8(e.getSymbol().getName().c_str());
+
+ os_sprintf(pstError, _("Undefined variable: %s\n"), strErr);
+ pwstError = to_wide_string(pstError);
+ FREE(strErr);
+ std::wstring wstError(pwstError);
+ FREE(pwstError);
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(wstError, 999, e.getLocation());
+ //Err, SimpleVar doesn't exist in Scilab scopes.
+ }
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const ColonVar & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ types::Colon *pC = new types::Colon();
+ setResult(pC);
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const DollarVar & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ setResult(types::Polynom::Dollar());
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const BreakExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ const_cast<BreakExp*>(&e)->setBreak();
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const ContinueExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ const_cast<ContinueExp*>(&e)->setContinue();
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const ArrayListExp & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ exps_t::const_iterator it;
+ int iNbExpSize = this->getExpectedSize();
+ this->setExpectedSize(1);
+
+ types::typed_list lstIT;
+ for (it = e.getExps().begin(); it != e.getExps().end(); it++)
+ {
+ (*it)->accept(*this);
+ for (int j = 0; j < getResultSize(); j++)
+ {
+ lstIT.push_back(getResult(j));
+ }
+ }
+
+ setResult(lstIT);
+
+ this->setExpectedSize(iNbExpSize);
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const VarDec & e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
+ {
+ /*getting what to assign*/
+ e.getInit().accept(*this);
+ getResult()->IncreaseRef();
+ }
+ catch (const InternalError& error)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw error;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const CellExp & e)
{
- std::list<MatrixLineExp *>::const_iterator row;
- std::list<Exp *>::const_iterator col;
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+
+ exps_t::const_iterator row;
+ exps_t::const_iterator col;
int iColMax = 0;
+ exps_t lines = e.getLines();
//check dimmension
- for (row = e.getLines().begin() ; row != e.getLines().end() ; ++row )
+ for (row = lines.begin(); row != lines.end(); ++row)
{
+ exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
if (iColMax == 0)
{
- iColMax = static_cast<int>((*row)->getColumns().size());
+ iColMax = static_cast<int>(cols.size());
}
- if (iColMax != static_cast<int>((*row)->getColumns().size()))
+ if (iColMax != static_cast<int>(cols.size()))
{
std::wostringstream os;
os << _W("inconsistent row/column dimensions\n");
//os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
- throw ScilabError(os.str(), 999, (*row)->getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(os.str(), 999, (*row)->getLocation());
}
}
//alloc result cell
- types::Cell *pC = new types::Cell(static_cast<int>(e.getLines().size()), iColMax);
+ types::Cell *pC = new types::Cell(static_cast<int>(lines.size()), iColMax);
int i = 0;
int j = 0;
//insert items in cell
- for (i = 0, row = e.getLines().begin() ; row != e.getLines().end() ; ++row, ++i)
+ for (i = 0, row = lines.begin(); row != lines.end(); ++row, ++i)
{
- for (j = 0, col = (*row)->getColumns().begin() ; col != (*row)->getColumns().end() ; ++col, ++j)
+ exps_t cols = (*row)->getAs<MatrixLineExp>()->getColumns();
+ for (j = 0, col = cols.begin(); col != cols.end(); ++col, ++j)
{
- (*col)->accept(*this);
- InternalType *pIT = getResult();
+ try
+ {
+ (*col)->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ types::InternalType *pIT = getResult();
if (pIT->isImplicitList())
{
- InternalType * _pIT = pIT->getAs<ImplicitList>()->extractFullMatrix();
+ types::InternalType * _pIT = pIT->getAs<types::ImplicitList>()->extractFullMatrix();
pC->set(i, j, _pIT);
_pIT->killMe();
}
//return new cell
setResult(pC);
+
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
{
/*
a.b
- */
+ */
+
+ CoverageInstance::invokeAndStartChrono((void*)&e);
if (!e.getTail()->isSimpleVar())
{
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
try
{
e.getHead()->accept(*this);
}
- catch (const ScilabError& error)
+ catch (const InternalError& error)
{
+ CoverageInstance::stopChrono((void*)&e);
throw error;
}
{
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
// TODO: handle case where getSize() > 1
clearResult();
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
std::wstring wstField = psvRightMember->getSymbol().getName();
- InternalType * pValue = getResult();
- InternalType * pReturn = NULL;
- bool ok;
+ types::InternalType * pValue = getResult();
+ types::InternalType * pReturn = NULL;
+ bool ok = false;
try
{
- ok = pValue->extract(wstField, pReturn);
+ if (pValue->isGenericType() || pValue->isUserType())
+ {
+ ok = pValue->getAs<types::GenericType>()->extract(wstField, pReturn);
+ }
}
catch (std::wstring & err)
{
- pValue->killMe();
- throw ScilabError(err.c_str(), 999, e.getTail()->getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
}
if (ok)
{
+ if (pReturn == NULL)
+ {
+ std::wostringstream os;
+ os << _W("Invalid index.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(os.str(), 999, e.getLocation());
+ }
+
setResult(pReturn);
+ if (pValue->isDeletable())
+ {
+ if (pValue->isContainer())
+ {
+ // prevent delete of pReturn in case where
+ // extract not return a clone
+ pReturn->IncreaseRef();
+ pValue->killMe();
+ pReturn->DecreaseRef();
+ }
+ else
+ {
+ pValue->killMe();
+ }
+ }
}
else if (pValue->isFieldExtractionOverloadable())
{
types::typed_list in;
types::typed_list out;
- String* pS = new String(wstField.c_str());
+ types::String* pS = new types::String(wstField.c_str());
//TODO: in the case where overload is a macro there is no need to incref in
// because args will be put in context, removed and killed if required.
in.push_back(pS);
in.push_back(pValue);
+ types::Callable::ReturnValue Ret = types::Callable::Error;
+ std::wstring stType = pValue->getShortTypeStr();
- Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_e", in, 1, out, this);
+ try
+ {
+ Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, true);
+ }
+ catch (const InternalError& ie)
+ {
+ try
+ {
+ //to compatibility with scilab 5 code.
+ //tlist/mlist name are truncated to 8 first character
+ if (stType.size() > 8)
+ {
+ Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, true);
+ }
+ else
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
+ }
+ catch (const InternalError& ie)
+ {
+ // TList or Mlist
+ if (pValue->isList())
+ {
+ Ret = Overload::call(L"%l_e", in, 1, out, true);
+ }
+ else
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
+ }
+ }
- if (Ret != Callable::OK)
+ if (Ret != types::Callable::OK)
{
cleanInOut(in, out);
- throw ScilabError();
+ setResult(NULL);
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
}
setResult(out);
pValue->killMe();
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("Attempt to reference field of non-structure array.\n").c_str());
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
+
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const IfExp &e)
{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+
//Create local exec visitor
ShortCutVisitor SCTest;
bool bTestStatus = false;
//condition
- e.getTest().accept(SCTest);
- e.getTest().accept(*this);
+ try
+ {
+ e.getTest().accept(SCTest);
+ e.getTest().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
bTestStatus = getResult()->isTrue();
clearResult();
- if (bTestStatus == true)
+ try
{
- //condition == true
- if (e.isBreakable())
- {
- const_cast<IfExp*>(&e)->resetBreak();
- const_cast<Exp*>(&e.getThen())->setBreakable();
- }
-
- if (e.isContinuable())
+ if (bTestStatus == true)
{
- const_cast<IfExp*>(&e)->resetContinue();
- const_cast<Exp*>(&e.getThen())->setContinuable();
+ e.getThen().accept(*this);
}
-
- if (e.isReturnable())
+ else if (e.hasElse())
{
- const_cast<IfExp*>(&e)->resetReturn();
- const_cast<Exp*>(&e.getThen())->setReturnable();
+ e.getElse().accept(*this);
}
-
- e.getThen().accept(*this);
}
- else
+ catch (ScilabException &)
{
- //condition == false
-
- if (e.hasElse())
- {
- if (e.isBreakable())
- {
- const_cast<Exp*>(&e.getElse())->setBreakable();
- }
-
- if (e.isContinuable())
- {
- const_cast<IfExp*>(&e)->resetContinue();
- const_cast<Exp*>(&e.getElse())->setContinuable();
- }
-
- if (e.isReturnable())
- {
- const_cast<Exp*>(&e.getElse())->setReturnable();
- }
-
- e.getElse().accept(*this);
- }
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
}
- if (e.isBreakable()
- && ( (&e.getElse())->isBreak()
- || (&e.getThen())->isBreak() ))
+ bool elseIsBreak = e.hasElse() && (&e.getElse())->isBreak();
+ if (e.isBreakable() && (elseIsBreak || (&e.getThen())->isBreak()))
{
const_cast<IfExp*>(&e)->setBreak();
- const_cast<Exp*>(&e.getElse())->resetBreak();
const_cast<Exp*>(&e.getThen())->resetBreak();
+ if (e.hasElse())
+ {
+ const_cast<Exp*>(&e.getElse())->resetBreak();
+ }
}
- if (e.isContinuable()
- && ( (&e.getElse())->isContinue()
- || (&e.getThen())->isContinue() ))
+ bool elseIsContinue = e.hasElse() && (&e.getElse())->isContinue();
+ if (e.isContinuable() && (elseIsContinue || (&e.getThen())->isContinue()))
{
const_cast<IfExp*>(&e)->setContinue();
- const_cast<Exp*>(&e.getElse())->resetContinue();
const_cast<Exp*>(&e.getThen())->resetContinue();
+ if (e.hasElse())
+ {
+ const_cast<Exp*>(&e.getElse())->resetContinue();
+ }
}
- if (e.isReturnable()
- && ( (&e.getElse())->isReturn()
- || (&e.getThen())->isReturn() ))
+ bool elseIsReturn = e.hasElse() && (&e.getElse())->isReturn();
+ if (e.isReturnable() && (elseIsReturn || (&e.getThen())->isReturn()))
{
const_cast<IfExp*>(&e)->setReturn();
- const_cast<Exp*>(&e.getElse())->resetReturn();
const_cast<Exp*>(&e.getThen())->resetReturn();
+ if (e.hasElse())
+ {
+ const_cast<Exp*>(&e.getElse())->resetReturn();
+ }
}
+
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const WhileExp &e)
{
- //allow break and continue operations
- const_cast<Exp*>(&e.getBody())->setBreakable();
- const_cast<Exp*>(&e.getBody())->setContinuable();
- //allow return operation
- if (e.isReturnable())
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+
+ //Create local exec visitor
+ ShortCutVisitor SCTest;
+
+ try
+ {
+ //manage & and | like && and ||
+ e.getTest().accept(SCTest);
+ //condition
+ e.getTest().accept(*this);
+ }
+ catch (ScilabException &)
{
- (&e.getBody())->isReturnable();
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
}
- //condition
- e.getTest().accept(*this);
- while (getResult()->isTrue())
+ types::InternalType* pIT = getResult();
+
+ while (pIT->isTrue())
{
- e.getBody().accept(*this);
+ pIT->killMe();
+ setResult(NULL);
+
+ try
+ {
+ e.getBody().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+
+ //clear old result value before evaluate new one
+ if (getResult() != NULL)
+ {
+ getResult()->killMe();
+ }
+
if (e.getBody().isBreak())
{
const_cast<Exp*>(&(e.getBody()))->resetBreak();
if (e.getBody().isContinue())
{
- const_cast<WhileExp*>(&e)->setContinue();
const_cast<Exp*>(&(e.getBody()))->resetContinue();
- e.getTest().accept(*this);
- continue;
}
- //clear old result value before evaluate new one
- if (getResult() != NULL)
+ try
{
- getResult()->killMe();
+ e.getTest().accept(*this);
}
-
- e.getTest().accept(*this);
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ pIT = getResult();
}
+ //pIT->killMe();
//clear result of condition or result of body
clearResult();
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const ForExp &e)
{
- e.getVardec().accept(*this);
- InternalType* pIT = getResult();
- //allow break and continue operations
- const_cast<Exp&>(e.getBody()).setBreakable();
- const_cast<Exp&>(e.getBody()).setContinuable();
-
- //allow return operation
- if (e.isReturnable())
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ symbol::Context* ctx = symbol::Context::getInstance();
+ //vardec visit increase its result reference
+ try
+ {
+ e.getVardec().accept(*this);
+ }
+ catch (ScilabException &)
{
- e.getBody().isReturnable();
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
}
+ types::InternalType* pIT = getResult();
- if (getResult()->isImplicitList())
+ if (pIT->isImplicitList())
{
- ImplicitList* pVar = pIT->getAs<ImplicitList>();
- for (int i = 0; i < pVar->getSize(); ++i)
+ //get IL
+ types::ImplicitList* pVar = pIT->getAs<types::ImplicitList>();
+ //get IL initial Type
+ types::InternalType * pIL = pVar->getInitalType();
+ //std::cout << "for IL: " << pIL << std::endl;
+ //std::cout << " for IV: " << pIT << std::endl;
+ //get index stack
+ symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
+
+ if (ctx->isprotected(var))
{
- //TODO : maybe it would be interesting here to reuse the same InternalType (to avoid delete/new)
- InternalType * pIL = pVar->extractValue(i);
- symbol::Context::getInstance()->put(e.getVardec().getStack(), pIL);
+ std::wostringstream os;
+ os << _W("Redefining permanent variable.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
+ }
+
+ ctx->put(var, pIL);
+ //use ref count to lock var against clear and detect any changes
+ pIL->IncreaseRef();
+
+ int size = static_cast<int>(pVar->getSize());
+ for (int i = 0; i < size; ++i)
+ {
+ //check if loop index has changed, deleted, copy ...
+ if (pIL->getRef() != 2)
+ {
+ switch (pIL->getRef())
+ {
+ case 1:
+ //someone clear me
+ ctx->put(var, pIL);
+ break;
+ default:
+ //someone assign me to another var
+ //a = i;
+ //unlock me
+ pIL->DecreaseRef();
+
+ //no need to destroy, it already assign to another var
+ //pIL->killMe();
+
+ //create a new me
+ pIL = pVar->getInitalType();
+ //lock loop index
+ pIL->IncreaseRef();
+ //update me ( must decrease ref of a )
+ if (ctx->isprotected(var))
+ {
+ std::wostringstream os;
+ os << _W("Redefining permanent variable.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
+ }
+
+ ctx->put(var, pIL);
+ break;
+ }
+ }
+
+ pVar->extractValue(i, pIL);
+
+ try
+ {
+ e.getBody().accept(*this);
+ }
+ catch (const InternalError& ie)
+ {
+ //unlock loop index and implicit list
+ pIL->DecreaseRef();
+ pIL->killMe();
+ pIT->DecreaseRef();
+ pIT->killMe();
+
+ setResult(NULL);
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
- e.getBody().accept(*this);
if (e.getBody().isBreak())
{
const_cast<Exp&>(e.getBody()).resetBreak();
if (e.getBody().isReturn())
{
const_cast<ForExp&>(e).setReturn();
+ const_cast<Exp&>(e.getBody()).resetReturn();
break;
}
}
+
+ //unlock loop index
+ pIL->DecreaseRef();
+ pIL->killMe();
}
- else if (getResult()->isList())
+ else if (pIT->isList())
{
- List* pL = pIT->getAs<List>();
+ types::List* pL = pIT->getAs<types::List>();
const int size = pL->getSize();
+ symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
for (int i = 0; i < size; ++i)
{
- InternalType* pNew = pL->get(i);
- symbol::Context::getInstance()->put(e.getVardec().getStack(), pNew);
+ types::InternalType* pNew = pL->get(i);
+
+ if (ctx->isprotected(var))
+ {
+ std::wostringstream os;
+ os << _W("Redefining permanent variable.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw ast::InternalError(os.str(), 999, e.getVardec().getLocation());
+ }
+ ctx->put(var, pNew);
+
+ try
+ {
+ e.getBody().accept(*this);
+ }
+ catch (const InternalError& ie)
+ {
+ //implicit list
+ pIT->DecreaseRef();
+ pIT->killMe();
+ setResult(NULL);
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
- e.getBody().accept(*this);
if (e.getBody().isBreak())
{
const_cast<Exp*>(&(e.getBody()))->resetBreak();
if (e.getBody().isReturn())
{
const_cast<ForExp*>(&e)->setReturn();
+ const_cast<Exp&>(e.getBody()).resetReturn();
break;
}
}
}
- else
+ else if (pIT->isGenericType())
{
//Matrix i = [1,3,2,6] or other type
- GenericType* pVar = pIT->getAs<GenericType>();
+ types::GenericType* pVar = pIT->getAs<types::GenericType>();
if (pVar->getDims() > 2)
{
pIT->DecreaseRef();
pIT->killMe();
-
- throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
}
+ symbol::Variable* var = e.getVardec().getAs<VarDec>()->getStack();
for (int i = 0; i < pVar->getCols(); i++)
{
- GenericType* pNew = pVar->getColumnValues(i);
- symbol::Context::getInstance()->put(e.getVardec().getStack(), pNew);
+ types::GenericType* pNew = pVar->getColumnValues(i);
+ if (pNew == NULL)
+ {
+ pIT->DecreaseRef();
+ pIT->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
+ }
+
+ if (ctx->isprotected(var))
+ {
+ std::wostringstream os;
+ os << _W("Redefining permanent variable.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(os.str(), 999, e.getVardec().getLocation());
+ }
+ ctx->put(var, pNew);
+
+ try
+ {
+ e.getBody().accept(*this);
+ }
+ catch (const InternalError& ie)
+ {
+ //implicit list
+ pIT->DecreaseRef();
+ pIT->killMe();
+ setResult(NULL);
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
- e.getBody().accept(*this);
if (e.getBody().isBreak())
{
const_cast<Exp*>(&(e.getBody()))->resetBreak();
if (e.getBody().isReturn())
{
const_cast<ForExp*>(&e)->setReturn();
+ const_cast<Exp&>(e.getBody()).resetReturn();
break;
}
}
}
+ else
+ {
+ pIT->DecreaseRef();
+ pIT->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
+ }
pIT->DecreaseRef();
pIT->killMe();
setResult(NULL);
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const ReturnExp &e)
{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
if (e.isGlobal())
{
- //return or resume
- if (ConfigVariable::getPauseLevel() != 0)
+ if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
{
- ThreadId* pThreadId = ConfigVariable::getLastPausedThread();
- if (pThreadId == NULL)
- {
- //no paused thread, so just go leave
- return;
- }
-
- //force exit without prompt of current thread ( via Aborted status )
- ThreadId* pMe = ConfigVariable::getThread(__GetCurrentThreadKey());
- pMe->setStatus(ThreadId::Aborted);
-
- //resume previous execution thread
- pThreadId->resume();
-
+ //return or resume
+ ConfigVariable::DecreasePauseLevel();
+ ConfigVariable::macroFirstLine_end();
+ CoverageInstance::stopChrono((void*)&e);
return;
}
else
{
//return(x)
- //in case of CallExp, we can return only one values
+ if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
+ }
+ //in case of CallExp, we can return only one value
int iSaveExpectedSize = getExpectedSize();
setExpectedSize(1);
- e.getExp().accept(*this);
+ try
+ {
+ e.getExp().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
setExpectedSize(iSaveExpectedSize);
+ const_cast<ReturnExp*>(&e)->setReturn();
+ }
+
+ CoverageInstance::stopChrono((void*)&e);
+}
- if (getResultSize() == 1)
+template <class T>
+void RunVisitorT<T>::visitprivate(const IntSelectExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ bool found = false;
+ //e.getSelect()->accept(*this);
+ //InternalType* pIT = getResult();
+ //setResult(nullptr);
+ //if (pIT && pIT->isDouble())
+ //{
+ // Double * pDbl = static_cast<Double *>(pIT);
+ // if (!pDbl->isComplex() && pDbl->getSize() == 1)
+ // {
+ // int64_t val;
+ // if (analysis::tools::asInteger<int64_t>(pDbl->get(0), val))
+ // {
+ // Exp * exp = e.getExp(val);
+ // found = true;
+ // if (exp)
+ // {
+ // Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
+ // if (e.isBreakable())
+ // {
+ // const_cast<IntSelectExp*>(&e)->resetBreak();
+ // body->setBreakable();
+ // }
+
+ // if (e.isContinuable())
+ // {
+ // const_cast<IntSelectExp*>(&e)->resetContinue();
+ // body->setContinuable();
+ // }
+
+ // if (e.isReturnable())
+ // {
+ // const_cast<IntSelectExp*>(&e)->resetReturn();
+ // body->setReturnable();
+ // }
+
+ // try
+ // {
+ // //the good one
+ // body->accept(*this);
+ // }
+ // catch (const InternalError& ie)
+ // {
+ // pIT->killMe();
+ // throw ie;
+ // }
+
+ // if (e.isBreakable() && body->isBreak())
+ // {
+ // const_cast<IntSelectExp*>(&e)->setBreak();
+ // body->resetBreak();
+ // }
+
+ // if (e.isContinuable() && body->isContinue())
+ // {
+ // const_cast<IntSelectExp*>(&e)->setContinue();
+ // body->resetContinue();
+ // }
+
+ // if (e.isReturnable() && body->isReturn())
+ // {
+ // const_cast<IntSelectExp*>(&e)->setReturn();
+ // body->resetReturn();
+ // }
+ // }
+ // }
+ // }
+ //}
+
+ if (!found)
+ {
+ try
{
- //protect variable
- getResult()->IncreaseRef();
+ e.getOriginal()->accept(*this);
}
- else
+ catch (ScilabException &)
{
- for (int i = 0 ; i < getResultSize() ; i++)
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ }
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
+ {
+ e.getSelect()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ types::InternalType* pIT = getResult();
+ setResult(nullptr);
+ bool found = false;
+ if (pIT && pIT->isString())
+ {
+ types::String * pStr = static_cast<types::String *>(pIT);
+ if (pStr->getSize() == 1)
+ {
+ if (wchar_t * s = pStr->get(0))
{
- //protect variable
- getResult(i)->IncreaseRef();
+ const std::wstring ws(s);
+ Exp * exp = e.getExp(ws);
+ found = true;
+ if (exp)
+ {
+ Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
+ if (e.isBreakable())
+ {
+ const_cast<StringSelectExp*>(&e)->resetBreak();
+ body->setBreakable();
+ }
+
+ if (e.isContinuable())
+ {
+ const_cast<StringSelectExp*>(&e)->resetContinue();
+ body->setContinuable();
+ }
+
+ if (e.isReturnable())
+ {
+ const_cast<StringSelectExp*>(&e)->resetReturn();
+ body->setReturnable();
+ }
+
+ try
+ {
+ //the good one
+ body->accept(*this);
+ }
+ catch (const InternalError& ie)
+ {
+ pIT->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
+ }
+
+ if (e.isBreakable() && body->isBreak())
+ {
+ const_cast<StringSelectExp*>(&e)->setBreak();
+ body->resetBreak();
+ }
+
+ if (e.isContinuable() && body->isContinue())
+ {
+ const_cast<StringSelectExp*>(&e)->setContinue();
+ body->resetContinue();
+ }
+
+ if (e.isReturnable() && body->isReturn())
+ {
+ const_cast<StringSelectExp*>(&e)->setReturn();
+ body->resetReturn();
+ }
+ }
}
}
+ }
- if (getResultSize() == 1)
+ if (!found)
+ {
+ try
{
- //unprotect variable
- getResult()->DecreaseRef();
+ e.getOriginal()->accept(*this);
}
- else
+ catch (ScilabException &)
{
- for (int i = 0 ; i < getResultSize() ; i++)
- {
- //unprotect variable
- getResult(i)->DecreaseRef();
- }
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
}
-
- const_cast<ReturnExp*>(&e)->setReturn();
}
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const SelectExp &e)
{
// FIXME : exec select ... case ... else ... end
- e.getSelect()->accept(*this);
- bool bCase = false;
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
+ {
+ e.getSelect()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ bool bCase = false;
- InternalType* pIT = getResult();
+ types::InternalType* pIT = getResult();
setResult(NULL);
if (pIT)
{
+ // protect pIT to avoid double free when
+ // the variable in select is override in the case
+ pIT->IncreaseRef();
+
//find good case
- cases_t::iterator it;
- for (it = e.getCases()->begin(); it != e.getCases()->end() ; it++)
+ exps_t cases = e.getCases();
+ for (auto exp : cases)
{
- CaseExp* pCase = *it;
- pCase->getTest()->accept(*this);
- InternalType *pITCase = getResult();
+ CaseExp * pCase = exp->getAs<CaseExp>();
+ try
+ {
+ pCase->getTest()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ types::InternalType *pITCase = getResult();
setResult(NULL);
if (pITCase)
{
}
else if (*pITCase == *pIT)
{
- if (e.isBreakable())
- {
- const_cast<SelectExp*>(&e)->resetBreak();
- pCase->getBody()->setBreakable();
- }
-
- if (e.isContinuable())
+ try
{
- const_cast<SelectExp*>(&e)->resetContinue();
- pCase->getBody()->setContinuable();
+ //the good one
+ pCase->getBody()->accept(*this);
}
-
- if (e.isReturnable())
+ catch (const InternalError& ie)
{
- const_cast<SelectExp*>(&e)->resetReturn();
- pCase->getBody()->setReturnable();
+ pIT->DecreaseRef();
+ pIT->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
}
- //the good one
- pCase->getBody()->accept(*this);
-
if (e.isBreakable() && pCase->getBody()->isBreak())
{
const_cast<SelectExp*>(&e)->setBreak();
pCase->getBody()->resetReturn();
}
+ pITCase->killMe();
bCase = true;
break;
}
+
+ pITCase->killMe();
}
}
}
if (bCase == false && e.getDefaultCase() != NULL)
{
- if (e.isBreakable())
+ try
{
- const_cast<SelectExp*>(&e)->resetBreak();
- e.getDefaultCase()->setBreakable();
+ //default case
+ e.getDefaultCase()->accept(*this);
}
-
- if (e.isContinuable())
+ catch (const InternalError& ie)
{
- const_cast<SelectExp*>(&e)->resetContinue();
- e.getDefaultCase()->setContinuable();
- }
-
- if (e.isReturnable())
- {
- const_cast<SelectExp*>(&e)->resetReturn();
- e.getDefaultCase()->setReturnable();
+ if (pIT)
+ {
+ pIT->DecreaseRef();
+ pIT->killMe();
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ throw ie;
}
- //default case
- e.getDefaultCase()->accept(*this);
-
if (e.isBreakable() && e.getDefaultCase()->isBreak())
{
const_cast<SelectExp*>(&e)->setBreak();
}
clearResult();
-}
-template <class T>
-void RunVisitorT<T>::visitprivate(const SeqExp &e)
-{
- //T execMe;
- std::list<Exp *>::const_iterator itExp;
-
- for (itExp = e.getExps().begin (); itExp != e.getExps().end (); ++itExp)
+ if (pIT)
{
- if (e.isBreakable())
- {
- (*itExp)->resetBreak();
- (*itExp)->setBreakable();
- }
-
- if (e.isContinuable())
- {
- (*itExp)->resetContinue();
- (*itExp)->setContinuable();
- }
-
- if (e.isReturnable())
- {
- (*itExp)->setReturnable();
- }
-
- try
- {
- //reset default values
- setResult(NULL);
- setExpectedSize(-1);
- (*itExp)->accept(*this);
- InternalType * pIT = getResult();
-
- if (pIT != NULL)
- {
- bool bImplicitCall = false;
- if (pIT->isCallable()) //to manage call without ()
- {
- Callable *pCall = pIT->getAs<Callable>();
- typed_list out;
- typed_list in;
- optional_list opt;
-
- try
- {
- //in this case of calling, we can return only one values
- int iSaveExpectedSize = getExpectedSize();
- setExpectedSize(1);
- Function::ReturnValue Ret = pCall->call(in, opt, getExpectedSize(), out, this);
- setExpectedSize(iSaveExpectedSize);
-
- if (Ret == Callable::OK)
- {
- if (out.size() == 0)
- {
- setResult(NULL);
- }
- else
- {
- setResult(out[0]);
- }
- bImplicitCall = true;
- }
- else if (Ret == Callable::Error)
- {
- if (ConfigVariable::getLastErrorFunction() == L"")
- {
- ConfigVariable::setLastErrorFunction(pCall->getName());
- ConfigVariable::setLastErrorLine(e.getLocation().first_line);
- throw ScilabError();
- }
-
- if (pCall->isMacro() || pCall->isMacroFile())
- {
- wchar_t szError[bsiz];
- os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), (*itExp)->getLocation().first_line, pCall->getName().c_str());
- throw ScilabMessage(szError);
- }
- else
- {
- throw ScilabMessage();
- }
- }
- }
- catch (ScilabMessage sm)
- {
- wostringstream os;
- PrintVisitor printMe(os);
- (*itExp)->accept(printMe);
- //os << std::endl << std::endl;
- if (ConfigVariable::getLastErrorFunction() == L"")
- {
- ConfigVariable::setLastErrorFunction(pCall->getName());
- }
-
- if (pCall->isMacro() || pCall->isMacroFile())
- {
- wchar_t szError[bsiz];
- os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
- throw ScilabMessage(szError + os.str());
- }
- else
- {
- sm.SetErrorMessage(sm.GetErrorMessage() + os.str());
- throw sm;
- }
- }
- }
-
- //don't output Simplevar and empty result
- if (getResult() != NULL && (!(*itExp)->isSimpleVar() || bImplicitCall))
- {
- //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.getResult());
- InternalType* pITAns = getResult();
- symbol::Context::getInstance()->put(m_pAns, pITAns);
- if ((*itExp)->isVerbose() && ConfigVariable::isPromptShow())
- {
- //TODO manage multiple returns
- scilabWriteW(L" ans =\n\n");
- VariableToString(pITAns, L"ans");
- }
- }
-
- pIT->killMe();
- }
-
- if ((&e)->isBreakable() && (*itExp)->isBreak())
- {
- const_cast<SeqExp *>(&e)->setBreak();
- break;
- }
-
- if ((&e)->isContinuable() && (*itExp)->isContinue())
- {
- const_cast<SeqExp *>(&e)->setContinue();
- break;
- }
-
- if ((&e)->isReturnable() && (*itExp)->isReturn())
- {
- const_cast<SeqExp *>(&e)->setReturn();
- (*itExp)->resetReturn();
- break;
- }
- }
- catch (const ScilabMessage& sm)
- {
- scilabErrorW(sm.GetErrorMessage().c_str());
-
- CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
- if (pCall != NULL)
- {
- //to print call expression only of it is a macro
- pCall->getName().accept(*this);
-
- if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
- {
- wostringstream os;
- PrintVisitor printMe(os);
- pCall->accept(printMe);
- //os << std::endl << std::endl;
- if (ConfigVariable::getLastErrorFunction() == L"")
- {
- ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
- }
- throw ScilabMessage(os.str(), 0, (*itExp)->getLocation());
- }
- }
-
- throw ScilabMessage((*itExp)->getLocation());
- }
- catch (const ScilabError& se)
- {
- // check on error number because error message can be empty.
- if (ConfigVariable::getLastErrorNumber() == 0)
- {
- ConfigVariable::setLastErrorMessage(se.GetErrorMessage());
- ConfigVariable::setLastErrorNumber(se.GetErrorNumber());
- ConfigVariable::setLastErrorLine(se.GetErrorLocation().first_line);
- ConfigVariable::setLastErrorFunction(wstring(L""));
- }
-
- CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
- if (pCall != NULL)
- {
- //to print call expression only of it is a macro
- try
- {
- pCall->getName().accept(*this);
- if (getResult() != NULL && (getResult()->isMacro() || getResult()->isMacroFile()))
- {
- wostringstream os;
- PrintVisitor printMe(os);
- pCall->accept(printMe);
- //os << std::endl << std::endl;
- ConfigVariable::setLastErrorFunction(((InternalType*)getResult())->getAs<Callable>()->getName());
- scilabErrorW(se.GetErrorMessage().c_str());
- throw ScilabMessage(os.str(), 999, (*itExp)->getLocation());
- }
- }
- catch (ScilabError se2)
- {
- //just to catch exception, do nothing
- }
- }
-
- scilabErrorW(se.GetErrorMessage().c_str());
- scilabErrorW(L"\n");
- throw ScilabMessage((*itExp)->getLocation());
- }
-
- // If something other than NULL is given to setResult, then that would imply
- // to make a cleanup in visit(ForExp) for example (e.getBody().accept(*this);)
- setResult(NULL);
+ pIT->DecreaseRef();
+ pIT->killMe();
}
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const NotExp &e)
{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
/*
@ or ~ !
- */
- e.getExp().accept(*this);
+ */
+ try
+ {
+ e.getExp().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
- InternalType * pValue = getResult();
- InternalType * pReturn = NULL;
+ types::InternalType * pValue = getResult();
+ types::InternalType * pReturn = NULL;
if (pValue->neg(pReturn))
{
if (pValue != pReturn)
pValue->IncreaseRef();
in.push_back(pValue);
- Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, this);
+ types::Callable::ReturnValue Ret = Overload::call(L"%" + pValue->getShortTypeStr() + L"_5", in, 1, out, true);
- if (Ret != Callable::OK)
+ if (Ret != types::Callable::OK)
{
cleanInOut(in, out);
- throw ScilabError();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
}
setResult(out);
cleanIn(in, out);
}
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const TransposeExp &e)
{
- e.getExp().accept(*this);
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
+ {
+ e.getExp().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
if (getResultSize() != 1)
{
clearResult();
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("%ls: Can not transpose multiple elements.\n").c_str(), L"Transpose");
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
- InternalType * pValue = getResult();
- InternalType * pReturn = NULL;
+ types::InternalType * pValue = getResult();
+ types::InternalType * pReturn = NULL;
const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
}
setResult(pReturn);
+ CoverageInstance::stopChrono((void*)&e);
return;
}
pValue->IncreaseRef();
in.push_back(pValue);
- Callable::ReturnValue Ret;
+ types::Callable::ReturnValue Ret;
if (bConjug)
{
- Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, this);
+ Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, true);
}
else
{
- Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, this);
+ Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_0", in, 1, out, true);
}
- if (Ret != Callable::OK)
+ if (Ret != types::Callable::OK)
{
cleanInOut(in, out);
- throw ScilabError();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
}
setResult(out);
cleanIn(in, out);
}
+
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const FunctionDec & e)
{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ symbol::Context* ctx = symbol::Context::getInstance();
/*
function foo
endfunction
- */
+ */
// funcprot(0) : do nothing
// funcprot(1) && warning(on) : warning
//get input parameters list
std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
- const ArrayListVar *pListVar = &e.getArgs();
- for (std::list<Var *>::const_iterator i = pListVar->getVars().begin(), end = pListVar->getVars().end(); i != end; ++i)
+ const exps_t & vars = e.getArgs().getVars();
+ for (const auto var : vars)
{
- pVarList->push_back(static_cast<SimpleVar*>(*i)->getStack());
+ pVarList->push_back(var->getAs<SimpleVar>()->getStack());
}
//get output parameters list
std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
- const ArrayListVar *pListRet = &e.getReturns();
- for (std::list<Var *>::const_iterator i = pListRet->getVars().begin(), end = pListRet->getVars().end(); i != end; ++i)
+ const exps_t & rets = e.getReturns().getVars();
+ for (const auto ret : rets)
{
- pRetList->push_back(static_cast<SimpleVar*>(*i)->getStack());
+ pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
}
types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
- pMacro->setFirstLine(e.getLocation().first_line);
-
- bool bEquals = false;
- int iFuncProt = ConfigVariable::getFuncprot();
- if (iFuncProt != 0)
+ pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
+ if (e.getMacro())
{
- types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).getStack());
- if (pITFunc && pITFunc->isCallable())
- {
- if (pITFunc->isMacroFile())
- {
- types::MacroFile* pMF = pITFunc->getAs<types::MacroFile>();
- bEquals = *pMF->getMacro() == *pMacro;
- }
- else if (pITFunc->isMacro())
- {
- types::Macro* pM = pITFunc->getAs<types::Macro>();
- bEquals = *pM == *pMacro;
- }
- }
- else
- {
- bEquals = true; //avoid msg but keep assignation
- }
+ pMacro->setFileName(e.getMacro()->getFileName());
}
- if (bEquals == false && iFuncProt == 1 && ConfigVariable::getWarningMode())
+ if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
{
- wchar_t pwstFuncName[1024];
- os_swprintf(pwstFuncName, 1024, L"%-24ls", e.getSymbol().getName().c_str());
- char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
-
- sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
- sciprint("\n");
- FREE(pstFuncName);
+ delete pMacro;
+ std::wostringstream os;
+ os << _W("Redefining permanent variable.\n");
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(os.str(), 999, e.getLocation());
}
- else if (bEquals == false && iFuncProt == 2)
+
+ if (ctx->addMacro(pMacro) == false)
{
char pstError[1024];
char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
- sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
+ os_sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
wchar_t* pwstError = to_wide_string(pstError);
std::wstring wstError(pwstError);
FREE(pstFuncName);
FREE(pwstError);
- throw ScilabError(wstError, 999, e.getLocation());
+ pMacro->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(wstError, 999, e.getLocation());
}
- symbol::Context::getInstance()->addMacro(pMacro);
-
+ CoverageInstance::stopChrono((void*)&e);
}
template <class T>
void RunVisitorT<T>::visitprivate(const ListExp &e)
{
- e.getStart().accept(*this);
- GenericType* pITStart = static_cast<GenericType*>(getResult());
- if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<Double>()->isComplex())) &&
- pITStart->isList() == false) // list case => call overload
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
{
- pITStart->killMe();
+ e.getStart().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+
+ types::InternalType* pITStart = getResult();
+ types::GenericType* pStart = static_cast<types::GenericType*>(pITStart);
+ if (pITStart == NULL ||
+ ((pITStart->isGenericType() == false || pStart->getSize() != 1 || (pStart->isDouble() && pStart->getAs<types::Double>()->isComplex())) &&
+ pStart->isList() == false)) // list case => call overload
+ {
+ setResult(NULL);
wchar_t szError[bsiz];
- os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
- throw ScilabError(szError, 999, e.getLocation());
+ if (pITStart && pITStart->isImplicitList())
+ {
+ os_swprintf(szError, bsiz, _W("%ls: Too many %ls or wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", L"':'", 1);
+ }
+ else
+ {
+ os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 1);
+ }
+
+ if (pITStart)
+ {
+ pITStart->killMe();
+ }
+
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
- InternalType * piStart = pITStart;
- e.getStep().accept(*this);
- GenericType* pITStep = static_cast<GenericType*>(getResult());
- if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<Double>()->isComplex())) &&
- pITStep->isList() == false) // list case => call overload
+ try
+ {
+ e.getStep().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+
+ types::InternalType* pITStep = getResult();
+ types::GenericType* pStep = static_cast<types::GenericType*>(pITStep);
+ setResult(NULL);
+ if (pITStep == NULL ||
+ ((pITStep->isGenericType() == false || pStep->getSize() != 1 || (pStep->isDouble() && pStep->getAs<types::Double>()->isComplex())) &&
+ pStep->isList() == false)) // list case => call overload
{
pITStart->killMe();
- pITStep->killMe();
+ if (pITStep)
+ {
+ pITStep->killMe();
+ }
+
+ setResult(NULL);
wchar_t szError[bsiz];
os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2);
- throw ScilabError(szError, 999, e.getLocation());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
- InternalType* piStep = pITStep;
- e.getEnd().accept(*this);
- GenericType* pITEnd = static_cast<GenericType*>(getResult());
- if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<Double>()->isComplex())) &&
- pITEnd->isList() == false) // list case => call overload
+ try
+ {
+ e.getEnd().accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+
+ types::InternalType* pITEnd = getResult();
+ types::GenericType* pEnd = static_cast<types::GenericType*>(pITEnd);
+ setResult(NULL);
+ if (pITEnd == NULL ||
+ ((pITEnd->isGenericType() == false || pEnd->getSize() != 1 || (pEnd->isDouble() && pEnd->getAs<types::Double>()->isComplex())) &&
+ pEnd->isList() == false)) // list case => call overload
{
pITStart->killMe();
pITStep->killMe();
- pITEnd->killMe();
+ if (pITEnd)
+ {
+ pITEnd->killMe();
+ }
+
+ setResult(NULL);
wchar_t szError[bsiz];
- os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 3);
- throw ScilabError(szError, 999, e.getLocation());
+ os_swprintf(szError, bsiz, _W("%ls: Wrong type for argument %d: Real scalar expected.\n").c_str(), L"':'", 2 + e.hasExplicitStep());
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(szError, 999, e.getLocation());
}
- InternalType* piEnd = pITEnd;
+
+ ////check if implicitlist is 1:$ to replace by ':'
+ //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
+ //{
+ // if (piStart->getAs<Double>()->get()[0] == 1 && piStep->getAs<Double>()->get()[0] == 1)
+ // {
+ // SinglePoly* end = piEnd->getAs<Polynom>()->get()[0];
+ // if (end->getRank() == 1 && end->get()[0] == 0 && end->get()[1] == 1)
+ // {
+ // setResult(new Colon());
+ // return;
+ // }
+ // }
+ //}
//check compatibility
// double : double : double or poly : poly : poly and mix like double : double : poly
- if ((piStart->isPoly() || piStart->isDouble()) &&
- (piStep->isPoly() || piStep->isDouble()) &&
- (piEnd->isPoly() || piEnd->isDouble()))
+ if ((pStart->isPoly() || pStart->isDouble()) &&
+ (pStep->isPoly() || pStep->isDouble()) &&
+ (pEnd->isPoly() || pEnd->isDouble()))
{
// No need to kill piStart, ... because Implicit list ctor will incref them
- setResult(new ImplicitList(piStart, piStep, piEnd));
+ setResult(new types::ImplicitList(pStart, pStep, pEnd));
+ CoverageInstance::stopChrono((void*)&e);
return;
}
// int : double or int : int
- if ( piStart->isInt() &&
- (piStep->isDouble() || piStep->isInt()) &&
- piEnd->isInt())
+ if (pStart->isInt() &&
+ (pStep->isDouble() || pStep->isInt()) &&
+ pEnd->isInt())
{
// check for same int type int8, int 16 ...
- if (piStart->getType() == piEnd->getType() &&
- (piStart->getType() == piStep->getType() ||
- piStep->isDouble()))
+ if (pStart->getType() == pEnd->getType() &&
+ (pStart->getType() == pStep->getType() ||
+ pStep->isDouble()))
{
// No need to kill piStart, ... because Implicit list ctor will incref them
- setResult(new ImplicitList(piStart, piStep, piEnd));
+ setResult(new types::ImplicitList(pStart, pStep, pEnd));
+ CoverageInstance::stopChrono((void*)&e);
return;
}
}
// Call Overload
- Callable::ReturnValue Ret;
+ types::Callable::ReturnValue Ret;
types::typed_list in;
types::typed_list out;
- piStart->IncreaseRef();
- piStep->IncreaseRef();
- piEnd->IncreaseRef();
+ pStart->IncreaseRef();
+ in.push_back(pStart);
- in.push_back(piStart);
- if (e.hasExplicitStep())
+ try
{
- // 1:2:4
- //call overload %typeStart_b_typeEnd
- in.push_back(piStep);
- in.push_back(piEnd);
- Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, this, true);
+ if (e.hasExplicitStep())
+ {
+ // 1:2:4
+ //call overload %typeStart_b_typeStep
+ pStep->IncreaseRef();
+ in.push_back(pStep);
+ pEnd->IncreaseRef();
+ in.push_back(pEnd);
+ Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pStep->getShortTypeStr(), in, 1, out, true);
+ }
+ else
+ {
+ // 1:2
+ //call overload %typeStart_b_typeEnd
+ pStep->killMe();
+ pEnd->IncreaseRef();
+ in.push_back(pEnd);
+ Ret = Overload::call(L"%" + pStart->getShortTypeStr() + L"_b_" + pEnd->getShortTypeStr(), in, 1, out, true);
+ }
}
- else
+ catch (const InternalError& error)
{
- // 1:2
- //call overload %typeStart_b_typeStep
- in.push_back(piEnd);
- Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, this, true);
+ setResult(NULL);
+ cleanInOut(in, out);
+ CoverageInstance::stopChrono((void*)&e);
+ throw error;
}
- if (Ret != Callable::OK)
+ if (Ret != types::Callable::OK)
{
+ setResult(NULL);
cleanInOut(in, out);
- throw ScilabError();
+ CoverageInstance::stopChrono((void*)&e);
+ throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
}
setResult(out);
cleanIn(in, out);
+ CoverageInstance::stopChrono((void*)&e);
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const OptimizedExp &e)
+{
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const MemfillExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+}
+
+template <class T>
+void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ types::InternalType* pIT = NULL;
+ types::Double* ad = NULL;
+ int ar = 0;
+ int ac = 0;
+
+ types::Double* xd = NULL;
+ int xr = 0;
+ int xc = 0;
+
+ types::Double* yd = NULL;
+ int yr = 0;
+ int yc = 0;
+
+ //check types and dimensions
+
+ //y must be double
+ const Exp &ye = e.getY();
+ try
+ {
+ ye.accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+
+ pIT = getResult();
+ if (pIT->isDouble())
+ {
+ yd = pIT->getAs<types::Double>();
+ if (yd->getDims() == 2 && yd->isComplex() == false)
+ {
+ yr = yd->getRows();
+ yc = yd->getCols();
+ }
+ else
+ {
+ yd->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+ }
+ else
+ {
+ pIT->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+
+ //x
+ const Exp &xe = e.getX();
+ try
+ {
+ xe.accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ pIT = getResult();
+
+ if (pIT->isDouble())
+ {
+ xd = pIT->getAs<types::Double>();
+ if (xd->isScalar() && xd->isComplex() == false)
+ {
+ // x become a
+ ad = xd;
+ ar = 1;
+ ac = 1;
+ }
+ else if (xd->getDims() == 2 && xd->isComplex() == false)
+ {
+ xr = xd->getRows();
+ xc = xd->getCols();
+ }
+ else
+ {
+ yd->killMe();
+ xd->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+ }
+ else
+ {
+ pIT->killMe();
+ yd->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+
+ const Exp &ae = e.getA();
+ try
+ {
+ ae.accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ pIT = getResult();
+
+ if (pIT->isDouble())
+ {
+ if (ad)
+ {
+ xd = pIT->getAs<types::Double>();
+ //X is scalar it become A
+ //now use A as X
+ if (xd->getDims() == 2 && xd->isComplex() == false)
+ {
+ xr = xd->getRows();
+ xc = xd->getCols();
+ }
+ else
+ {
+ yd->killMe();
+ xd->killMe();
+ ad->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+ }
+ else
+ {
+ //a is a and it must be scalar
+ ad = pIT->getAs<types::Double>();
+ if (/*ad->isScalar() && */ad->isComplex() == false)
+ {
+ ar = ad->getRows(); //1;
+ ac = ad->getCols();//1;
+ }
+ else
+ {
+ yd->killMe();
+ xd->killMe();
+ ad->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ throw;
+ return;
+ }
+ }
+ }
+ else
+ {
+ pIT->killMe();
+ yd->killMe();
+ xd->killMe();
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+
+ // If we get here we are certain that ad, xd & yd have been set
+ if (ac == 1 &&
+ ar == 1 &&
+ xr == yr &&
+ xc == yc)
+ {
+ //go !
+ int one = 1;
+ int size = xc * xr;
+ //Double* od = (Double*)yd->clone();
+ C2F(daxpy)(&size, ad->get(), xd->get(), &one, yd->get(), &one);
+ //setResult(od);
+ //yd->killMe();
+ xd->killMe();
+ ad->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+ else if (ac == xr && ar == yr && xc == yc)
+ {
+ char n = 'n';
+ double one = 1;
+ C2F(dgemm)(&n, &n, &ar, &xc, &ac, &one, ad->get(), &ar, xd->get(), &ac, &one, yd->get(), &ar);
+ xd->killMe();
+ ad->killMe();
+ CoverageInstance::stopChrono((void*)&e);
+ return;
+ }
+
+ yd->killMe();
+ xd->killMe();
+ ad->killMe();
+
+ try
+ {
+ e.getOriginal()->accept(*this);
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ CoverageInstance::stopChrono((void*)&e);
+
+ return;
}
-#include "run_CallExp.cpp"
-#include "run_MatrixExp.cpp"
-#include "run_OpExp.cpp"
-#include "run_AssignExp.cpp"
+template <class T>
+void RunVisitorT<T>::visitprivate(const TryCatchExp &e)
+{
+ CoverageInstance::invokeAndStartChrono((void*)&e);
+ //save current prompt mode
+ bool oldVal = ConfigVariable::isSilentError();
+ int oldMode = ConfigVariable::getPromptMode();
+ //set mode silent for errors
+ ConfigVariable::setSilentError(true);
+
+ symbol::Context* pCtx = symbol::Context::getInstance();
+ try
+ {
+ int scope = pCtx->getScopeLevel();
+ int level = ConfigVariable::getRecursionLevel();
+ try
+ {
+ const_cast<Exp*>(&e.getTry())->setReturnable();
+ e.getTry().accept(*this);
+ //restore previous prompt mode
+ ConfigVariable::setSilentError(oldVal);
+
+ if (e.getTry().isReturn())
+ {
+ const_cast<Exp*>(&e.getTry())->resetReturn();
+ const_cast<TryCatchExp*>(&e)->setReturn();
+ }
+ }
+ catch (const RecursionException& /* re */)
+ {
+ ConfigVariable::setPromptMode(oldMode);
+
+ //close opened scope during try
+ while (pCtx->getScopeLevel() > scope)
+ {
+ pCtx->scope_end();
+ }
+
+ //decrease recursion to init value and close where
+ while (ConfigVariable::getRecursionLevel() > level)
+ {
+ ConfigVariable::where_end();
+ ConfigVariable::decreaseRecursion();
+ }
+
+ //print msg about recursion limit and trigger an error
+ wchar_t sz[1024];
+ os_swprintf(sz, 1024, _W("Recursion limit reached (%d).\n").data(), ConfigVariable::getRecursionLimit());
+ CoverageInstance::stopChrono((void*)&e);
+ throw ast::InternalError(sz);
+ }
+
+ }
+ catch (const InternalError& /* ie */)
+ {
+ //restore previous prompt mode
+ ConfigVariable::setSilentError(oldVal);
+ //to lock lasterror
+ ConfigVariable::setLastErrorCall();
+ // reset call stack filled when error occurred
+ ConfigVariable::resetWhereError();
+ try
+ {
+ const_cast<Exp*>(&e.getCatch())->setReturnable();
+ e.getCatch().accept(*this);
+ if (e.getCatch().isReturn())
+ {
+ const_cast<Exp*>(&e.getCatch())->resetReturn();
+ const_cast<TryCatchExp*>(&e)->setReturn();
+ }
+ }
+ catch (ScilabException &)
+ {
+ CoverageInstance::stopChrono((void*)&e);
+ throw;
+ }
+ }
+ CoverageInstance::stopChrono((void*)&e);
}
+
+} /* namespace ast */
+
+#include "run_SeqExp.hpp"
+#include "run_CallExp.hpp"
+#include "run_MatrixExp.hpp"
+#include "run_OpExp.hpp"
+#include "run_AssignExp.hpp"
+
template EXTERN_AST class ast::RunVisitorT<ast::ExecVisitor>;
template EXTERN_AST class ast::RunVisitorT<ast::StepVisitor>;
template EXTERN_AST class ast::RunVisitorT<ast::TimedVisitor>;
+template EXTERN_AST class ast::RunVisitorT<ast::DebuggerVisitor>;