* Bug 16191 fixed: now mode(0) and mode(1) are really compact.
[scilab.git] / scilab / modules / ast / src / cpp / ast / runvisitor.cpp
index 92a2a4b..dc7d63d 100644 (file)
@@ -2,23 +2,33 @@
  *  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.lines_get().begin() ; row != e.lines_get().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)->columns_get().size());
+            iColMax = static_cast<int>(cols.size());
         }
 
-        if (iColMax != static_cast<int>((*row)->columns_get().size()))
+        if (iColMax != static_cast<int>(cols.size()))
         {
             std::wostringstream os;
             os << _W("inconsistent row/column dimensions\n");
-            //os << ((Location)(*row)->location_get()).location_getString() << std::endl;
-            throw ScilabError(os.str(), 999, (*row)->location_get());
+            //os << ((Location)(*row)->getLocation()).getLocationString() << std::endl;
+            CoverageInstance::stopChrono((void*)&e);
+            throw InternalError(os.str(), 999, (*row)->getLocation());
         }
     }
 
     //alloc result cell
-    types::Cell *pC = new types::Cell(static_cast<int>(e.lines_get().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.lines_get().begin() ; row != e.lines_get().end() ; ++row, ++i)
+    for (i = 0, row = lines.begin(); row != lines.end(); ++row, ++i)
     {
-        for (j = 0, col = (*row)->columns_get().begin() ; col != (*row)->columns_get().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 = result_get();
+            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();
             }
@@ -86,12 +305,14 @@ void RunVisitorT<T>::visitprivate(const CellExp &e)
             {
                 pC->set(i, j, pIT);
             }
-            result_clear();
+            clearResult();
         }
     }
 
     //return new cell
-    result_set(pC);
+    setResult(pC);
+
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
@@ -99,68 +320,100 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
 {
     /*
       a.b
-    */
+      */
+
+    CoverageInstance::invokeAndStartChrono((void*)&e);
 
-    if (!e.tail_get()->is_simple_var())
+    if (!e.getTail()->isSimpleVar())
     {
         wchar_t szError[bsiz];
         os_swprintf(szError, bsiz, _W("/!\\ Unmanaged FieldExp.\n").c_str());
-        throw ScilabError(szError, 999, e.location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(szError, 999, e.getLocation());
     }
 
     try
     {
-        e.head_get()->accept(*this);
+        e.getHead()->accept(*this);
     }
-    catch (const ScilabError& error)
+    catch (const InternalError& error)
     {
+        CoverageInstance::stopChrono((void*)&e);
         throw error;
     }
 
-    if (result_get() == NULL)
+    if (getResult() == NULL)
     {
         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.location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(szError, 999, e.getLocation());
     }
 
     // TODO: handle case where getSize() > 1
     // l=list(struct("toto","coucou"),struct("toto","hello"),1,2);[a,b]=l(1:2).toto
     //
-    if (result_getSize() > 1)
+    if (getResultSize() > 1)
     {
-        result_clear();
+        clearResult();
         wchar_t szError[bsiz];
         os_swprintf(szError, bsiz, _W("Not yet implemented in Scilab.\n").c_str());
-        throw ScilabError(szError, 999, e.location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(szError, 999, e.getLocation());
     }
 
-    SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.tail_get()));
-    std::wstring wstField = psvRightMember->name_get().name_get();
-    InternalType * pValue = result_get();
-    InternalType * pReturn = NULL;
-    bool ok;
+    SimpleVar * psvRightMember = static_cast<SimpleVar *>(const_cast<Exp *>(e.getTail()));
+    std::wstring wstField = psvRightMember->getSymbol().getName();
+    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.tail_get()->location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(err.c_str(), 999, e.getTail()->getLocation());
     }
 
     if (ok)
     {
-        result_set(pReturn);
+        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.
@@ -171,702 +424,865 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
 
         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)
         {
-            clean_in_out(in, out);
-            throw ScilabError();
+            cleanInOut(in, out);
+            setResult(NULL);
+            CoverageInstance::stopChrono((void*)&e);
+            throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
         }
 
-        result_set(out);
-        clean_in(in, out);
+        setResult(out);
+        cleanIn(in, out);
     }
     else
     {
         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.location_get());
+        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.test_get().accept(SCTest);
-    e.test_get().accept(*this);
-
-    bTestStatus = result_get()->isTrue();
-    result_clear();
-    if (bTestStatus == true)
+    try
     {
-        //condition == true
-        if (e.is_breakable())
-        {
-            const_cast<IfExp*>(&e)->break_reset();
-            const_cast<Exp*>(&e.then_get())->breakable_set();
-        }
+        e.getTest().accept(SCTest);
+        e.getTest().accept(*this);
+    }
+    catch (ScilabException &)
+    {
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
+    }
 
-        if (e.is_continuable())
+    bTestStatus = getResult()->isTrue();
+    clearResult();
+    try
+    {
+        if (bTestStatus == true)
         {
-            const_cast<IfExp*>(&e)->continue_reset();
-            const_cast<Exp*>(&e.then_get())->continuable_set();
+            e.getThen().accept(*this);
         }
-
-        if (e.is_returnable())
+        else if (e.hasElse())
         {
-            const_cast<IfExp*>(&e)->return_reset();
-            const_cast<Exp*>(&e.then_get())->returnable_set();
+            e.getElse().accept(*this);
         }
-
-        e.then_get().accept(*this);
     }
-    else
+    catch (ScilabException &)
     {
-        //condition == false
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
+    }
 
-        if (e.has_else())
+    bool elseIsBreak = e.hasElse() && (&e.getElse())->isBreak();
+    if (e.isBreakable() && (elseIsBreak || (&e.getThen())->isBreak()))
+    {
+        const_cast<IfExp*>(&e)->setBreak();
+        const_cast<Exp*>(&e.getThen())->resetBreak();
+        if (e.hasElse())
         {
-            if (e.is_breakable())
-            {
-                const_cast<Exp*>(&e.else_get())->breakable_set();
-            }
-
-            if (e.is_continuable())
-            {
-                const_cast<IfExp*>(&e)->continue_reset();
-                const_cast<Exp*>(&e.else_get())->continuable_set();
-            }
-
-            if (e.is_returnable())
-            {
-                const_cast<Exp*>(&e.else_get())->returnable_set();
-            }
-
-            e.else_get().accept(*this);
+            const_cast<Exp*>(&e.getElse())->resetBreak();
         }
     }
 
-    if (e.is_breakable()
-            && ( (&e.else_get())->is_break()
-                 || (&e.then_get())->is_break() ))
+    bool elseIsContinue = e.hasElse() && (&e.getElse())->isContinue();
+    if (e.isContinuable() && (elseIsContinue || (&e.getThen())->isContinue()))
     {
-        const_cast<IfExp*>(&e)->break_set();
-        const_cast<Exp*>(&e.else_get())->break_reset();
-        const_cast<Exp*>(&e.then_get())->break_reset();
+        const_cast<IfExp*>(&e)->setContinue();
+        const_cast<Exp*>(&e.getThen())->resetContinue();
+        if (e.hasElse())
+        {
+            const_cast<Exp*>(&e.getElse())->resetContinue();
+        }
     }
 
-    if (e.is_continuable()
-            && ( (&e.else_get())->is_continue()
-                 || (&e.then_get())->is_continue() ))
+    bool elseIsReturn = e.hasElse() && (&e.getElse())->isReturn();
+    if (e.isReturnable() && (elseIsReturn || (&e.getThen())->isReturn()))
     {
-        const_cast<IfExp*>(&e)->continue_set();
-        const_cast<Exp*>(&e.else_get())->continue_reset();
-        const_cast<Exp*>(&e.then_get())->continue_reset();
+        const_cast<IfExp*>(&e)->setReturn();
+        const_cast<Exp*>(&e.getThen())->resetReturn();
+        if (e.hasElse())
+        {
+            const_cast<Exp*>(&e.getElse())->resetReturn();
+        }
     }
 
-    if (e.is_returnable()
-            && ( (&e.else_get())->is_return()
-                 || (&e.then_get())->is_return() ))
-    {
-        const_cast<IfExp*>(&e)->return_set();
-        const_cast<Exp*>(&e.else_get())->return_reset();
-        const_cast<Exp*>(&e.then_get())->return_reset();
-    }
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
 void RunVisitorT<T>::visitprivate(const WhileExp  &e)
 {
-    //allow break and continue operations
-    const_cast<Exp*>(&e.body_get())->breakable_set();
-    const_cast<Exp*>(&e.body_get())->continuable_set();
-    //allow return operation
-    if (e.is_returnable())
+    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.body_get())->is_returnable();
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
     }
 
-    //condition
-    e.test_get().accept(*this);
-    while (result_get()->isTrue())
+    types::InternalType* pIT = getResult();
+
+    while (pIT->isTrue())
     {
-        e.body_get().accept(*this);
-        if (e.body_get().is_break())
+        pIT->killMe();
+        setResult(NULL);
+
+        try
         {
-            const_cast<Exp*>(&(e.body_get()))->break_reset();
-            break;
+            e.getBody().accept(*this);
+        }
+        catch (ScilabException &)
+        {
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
         }
 
-        if (e.body_get().is_return())
+        //clear old result value before evaluate new one
+        if (getResult() != NULL)
+        {
+            getResult()->killMe();
+        }
+
+        if (e.getBody().isBreak())
         {
-            const_cast<WhileExp*>(&e)->return_set();
-            const_cast<Exp*>(&(e.body_get()))->return_reset();
+            const_cast<Exp*>(&(e.getBody()))->resetBreak();
             break;
         }
 
-        if (e.body_get().is_continue())
+        if (e.getBody().isReturn())
         {
-            const_cast<WhileExp*>(&e)->continue_set();
-            const_cast<Exp*>(&(e.body_get()))->continue_reset();
-            e.test_get().accept(*this);
-            continue;
+            const_cast<WhileExp*>(&e)->setReturn();
+            const_cast<Exp*>(&(e.getBody()))->resetReturn();
+            break;
         }
 
-        //clear old result value before evaluate new one
-        if (result_get() != NULL)
+        if (e.getBody().isContinue())
         {
-            result_get()->killMe();
+            const_cast<Exp*>(&(e.getBody()))->resetContinue();
         }
 
-        e.test_get().accept(*this);
+        try
+        {
+            e.getTest().accept(*this);
+        }
+        catch (ScilabException &)
+        {
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
+        }
+        pIT = getResult();
     }
 
+    //pIT->killMe();
     //clear result of condition or result of body
-    result_clear();
+    clearResult();
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
 void RunVisitorT<T>::visitprivate(const ForExp  &e)
 {
-    e.vardec_get().accept(*this);
-    InternalType* pIT = result_get();
-    //allow break and continue operations
-    const_cast<Exp&>(e.body_get()).breakable_set();
-    const_cast<Exp&>(e.body_get()).continuable_set();
-
-    //allow return operation
-    if (e.is_returnable())
+    CoverageInstance::invokeAndStartChrono((void*)&e);
+    symbol::Context* ctx = symbol::Context::getInstance();
+    //vardec visit increase its result reference
+    try
+    {
+        e.getVardec().accept(*this);
+    }
+    catch (ScilabException &)
     {
-        e.body_get().is_returnable();
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
     }
+    types::InternalType* pIT = getResult();
 
-    if (result_get()->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))
+        {
+            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)
         {
-            //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.vardec_get().stack_get(), pIL);
+            //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.body_get().accept(*this);
-            if (e.body_get().is_break())
+            if (e.getBody().isBreak())
             {
-                const_cast<Exp&>(e.body_get()).break_reset();
+                const_cast<Exp&>(e.getBody()).resetBreak();
                 break;
             }
 
-            if (e.body_get().is_continue())
+            if (e.getBody().isContinue())
             {
-                const_cast<Exp&>(e.body_get()).continue_reset();
+                const_cast<Exp&>(e.getBody()).resetContinue();
                 continue;
             }
 
-            if (e.body_get().is_return())
+            if (e.getBody().isReturn())
             {
-                const_cast<ForExp&>(e).return_set();
+                const_cast<ForExp&>(e).setReturn();
+                const_cast<Exp&>(e.getBody()).resetReturn();
                 break;
             }
         }
+
+        //unlock loop index
+        pIL->DecreaseRef();
+        pIL->killMe();
     }
-    else if (result_get()->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.vardec_get().stack_get(), 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);
 
-            e.body_get().accept(*this);
-            if (e.body_get().is_break())
+            try
             {
-                const_cast<Exp*>(&(e.body_get()))->break_reset();
+                e.getBody().accept(*this);
+            }
+            catch (const InternalError& ie)
+            {
+                //implicit list
+                pIT->DecreaseRef();
+                pIT->killMe();
+                setResult(NULL);
+                CoverageInstance::stopChrono((void*)&e);
+                throw ie;
+            }
+
+            if (e.getBody().isBreak())
+            {
+                const_cast<Exp*>(&(e.getBody()))->resetBreak();
                 break;
             }
 
-            if (e.body_get().is_continue())
+            if (e.getBody().isContinue())
             {
-                const_cast<Exp*>(&(e.body_get()))->continue_reset();
+                const_cast<Exp*>(&(e.getBody()))->resetContinue();
                 continue;
             }
 
-            if (e.body_get().is_return())
+            if (e.getBody().isReturn())
             {
-                const_cast<ForExp*>(&e)->return_set();
+                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.vardec_get().location_get());
+            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.vardec_get().stack_get(), 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.body_get().accept(*this);
-            if (e.body_get().is_break())
+            if (e.getBody().isBreak())
             {
-                const_cast<Exp*>(&(e.body_get()))->break_reset();
+                const_cast<Exp*>(&(e.getBody()))->resetBreak();
                 break;
             }
 
-            if (e.body_get().is_continue())
+            if (e.getBody().isContinue())
             {
-                const_cast<Exp*>(&(e.body_get()))->continue_reset();
+                const_cast<Exp*>(&(e.getBody()))->resetContinue();
                 continue;
             }
 
-            if (e.body_get().is_return())
+            if (e.getBody().isReturn())
             {
-                const_cast<ForExp*>(&e)->return_set();
+                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();
 
-    result_set(NULL);
+    setResult(NULL);
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
 void RunVisitorT<T>::visitprivate(const ReturnExp &e)
 {
-    if (e.is_global())
+    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
         {
-            const_cast<ReturnExp*>(&e)->return_set();
+            const_cast<ReturnExp*>(&e)->setReturn();
         }
     }
     else
     {
         //return(x)
 
-        //in case of CallExp, we can return only one values
-        int iSaveExpectedSize = expected_getSize();
-        expected_setSize(1);
-        e.exp_get().accept(*this);
-        expected_setSize(iSaveExpectedSize);
-
-        if (result_getSize() == 1)
+        if (e.getParent() == nullptr || e.getParent()->isAssignExp() == false)
         {
-            //protect variable
-            result_get()->IncreaseRef();
+            CoverageInstance::stopChrono((void*)&e);
+            throw InternalError(_W("With input arguments, return / resume expects output arguments.\n"), 999, e.getLocation());
         }
-        else
+        //in case of CallExp, we can return only one value
+        int iSaveExpectedSize = getExpectedSize();
+        setExpectedSize(1);
+        try
         {
-            for (int i = 0 ; i < result_getSize() ; i++)
-            {
-                //protect variable
-                result_get(i)->IncreaseRef();
-            }
+            e.getExp().accept(*this);
+        }
+        catch (ScilabException &)
+        {
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
         }
+        setExpectedSize(iSaveExpectedSize);
+        const_cast<ReturnExp*>(&e)->setReturn();
+    }
+
+    CoverageInstance::stopChrono((void*)&e);
+}
 
-        if (result_getSize() == 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
         {
-            //unprotect variable
-            result_get()->DecreaseRef();
+            e.getOriginal()->accept(*this);
         }
-        else
+        catch (ScilabException &)
         {
-            for (int i = 0 ; i < result_getSize() ; i++)
-            {
-                //unprotect variable
-                result_get(i)->DecreaseRef();
-            }
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
         }
-
-        const_cast<ReturnExp*>(&e)->return_set();
     }
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
-void RunVisitorT<T>::visitprivate(const SelectExp &e)
+void RunVisitorT<T>::visitprivate(const StringSelectExp &e)
 {
-    // FIXME : exec select ... case ... else ... end
-    e.select_get()->accept(*this);
-    bool bCase = false;
-
-
-    InternalType* pIT = result_get();
-    result_set(NULL);
-    if (pIT)
+    CoverageInstance::invokeAndStartChrono((void*)&e);
+    try
     {
-        //find good case
-        cases_t::iterator it;
-        for (it = e.cases_get()->begin(); it != e.cases_get()->end() ; it++)
+        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)
         {
-            CaseExp* pCase = *it;
-            pCase->test_get()->accept(*this);
-            InternalType *pITCase = result_get();
-            result_set(NULL);
-            if (pITCase)
+            if (wchar_t * s = pStr->get(0))
             {
-                if (pITCase->isContainer()) //WARNING ONLY FOR CELL
-                {
-                    //check each item
-                }
-                else if (*pITCase == *pIT)
+                const std::wstring ws(s);
+                Exp * exp = e.getExp(ws);
+                found = true;
+                if (exp)
                 {
-                    if (e.is_breakable())
+                    Exp * body = exp->isCaseExp() ? exp->getAs<CaseExp>()->getBody() : exp;
+                    if (e.isBreakable())
                     {
-                        const_cast<SelectExp*>(&e)->break_reset();
-                        pCase->body_get()->breakable_set();
+                        const_cast<StringSelectExp*>(&e)->resetBreak();
+                        body->setBreakable();
                     }
 
-                    if (e.is_continuable())
+                    if (e.isContinuable())
                     {
-                        const_cast<SelectExp*>(&e)->continue_reset();
-                        pCase->body_get()->continuable_set();
+                        const_cast<StringSelectExp*>(&e)->resetContinue();
+                        body->setContinuable();
                     }
 
-                    if (e.is_returnable())
+                    if (e.isReturnable())
                     {
-                        const_cast<SelectExp*>(&e)->return_reset();
-                        pCase->body_get()->returnable_set();
+                        const_cast<StringSelectExp*>(&e)->resetReturn();
+                        body->setReturnable();
                     }
 
-                    //the good one
-                    pCase->body_get()->accept(*this);
-
-                    if (e.is_breakable() && pCase->body_get()->is_break())
+                    try
+                    {
+                        //the good one
+                        body->accept(*this);
+                    }
+                    catch (const InternalError& ie)
                     {
-                        const_cast<SelectExp*>(&e)->break_set();
-                        pCase->body_get()->break_reset();
+                        pIT->killMe();
+                        CoverageInstance::stopChrono((void*)&e);
+                        throw ie;
                     }
 
-                    if (e.is_continuable() && pCase->body_get()->is_continue())
+                    if (e.isBreakable() && body->isBreak())
                     {
-                        const_cast<SelectExp*>(&e)->continue_set();
-                        pCase->body_get()->continue_reset();
+                        const_cast<StringSelectExp*>(&e)->setBreak();
+                        body->resetBreak();
                     }
 
-                    if (e.is_returnable() && pCase->body_get()->is_return())
+                    if (e.isContinuable() && body->isContinue())
                     {
-                        const_cast<SelectExp*>(&e)->return_set();
-                        pCase->body_get()->return_reset();
+                        const_cast<StringSelectExp*>(&e)->setContinue();
+                        body->resetContinue();
                     }
 
-                    bCase = true;
-                    break;
+                    if (e.isReturnable() && body->isReturn())
+                    {
+                        const_cast<StringSelectExp*>(&e)->setReturn();
+                        body->resetReturn();
+                    }
                 }
             }
         }
     }
 
-    if (bCase == false && e.default_case_get() != NULL)
+    if (!found)
     {
-        if (e.is_breakable())
-        {
-            const_cast<SelectExp*>(&e)->break_reset();
-            e.default_case_get()->breakable_set();
-        }
-
-        if (e.is_continuable())
-        {
-            const_cast<SelectExp*>(&e)->continue_reset();
-            e.default_case_get()->continuable_set();
-        }
-
-        if (e.is_returnable())
-        {
-            const_cast<SelectExp*>(&e)->return_reset();
-            e.default_case_get()->returnable_set();
-        }
-
-        //default case
-        e.default_case_get()->accept(*this);
-
-        if (e.is_breakable() && e.default_case_get()->is_break())
-        {
-            const_cast<SelectExp*>(&e)->break_set();
-            e.default_case_get()->break_reset();
-        }
-
-        if (e.is_continuable() && e.default_case_get()->is_continue())
+        try
         {
-            const_cast<SelectExp*>(&e)->continue_set();
-            e.default_case_get()->continue_reset();
+            e.getOriginal()->accept(*this);
         }
-
-        if (e.is_returnable() && e.default_case_get()->is_return())
+        catch (ScilabException &)
         {
-            const_cast<SelectExp*>(&e)->return_set();
-            e.default_case_get()->return_reset();
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
         }
     }
-
-    result_clear();
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
-void RunVisitorT<T>::visitprivate(const SeqExp  &e)
+void RunVisitorT<T>::visitprivate(const SelectExp &e)
 {
-    //T execMe;
-    std::list<Exp *>::const_iterator        itExp;
-
-    for (itExp = e.exps_get().begin (); itExp != e.exps_get().end (); ++itExp)
+    // FIXME : exec select ... case ... else ... end
+    CoverageInstance::invokeAndStartChrono((void*)&e);
+    try
     {
-        if (e.is_breakable())
-        {
-            (*itExp)->break_reset();
-            (*itExp)->breakable_set();
-        }
+        e.getSelect()->accept(*this);
+    }
+    catch (ScilabException &)
+    {
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
+    }
 
-        if (e.is_continuable())
-        {
-            (*itExp)->continue_reset();
-            (*itExp)->continuable_set();
-        }
+    bool bCase = false;
 
-        if (e.is_returnable())
-        {
-            (*itExp)->returnable_set();
-        }
+    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();
 
-        try
+        //find good case
+        exps_t cases = e.getCases();
+        for (auto exp : cases)
         {
-            //reset default values
-            result_set(NULL);
-            expected_setSize(-1);
-            (*itExp)->accept(*this);
-            InternalType * pIT = result_get();
-
-            if (pIT != NULL)
+            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)
             {
-                bool bImplicitCall = false;
-                if (pIT->isCallable()) //to manage call without ()
+                if (pITCase->isContainer()) //WARNING ONLY FOR CELL
+                {
+                    //check each item
+                }
+                else if (*pITCase == *pIT)
                 {
-                    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 = expected_getSize();
-                        expected_setSize(1);
-                        Function::ReturnValue Ret = pCall->call(in, opt, expected_getSize(), out, this);
-                        expected_setSize(iSaveExpectedSize);
-
-                        if (Ret == Callable::OK)
-                        {
-                            if (out.size() == 0)
-                            {
-                                result_set(NULL);
-                            }
-                            else
-                            {
-                                result_set(out[0]);
-                            }
-                            bImplicitCall = true;
-                        }
-                        else if (Ret == Callable::Error)
-                        {
-                            if (ConfigVariable::getLastErrorFunction() == L"")
-                            {
-                                ConfigVariable::setLastErrorFunction(pCall->getName());
-                                ConfigVariable::setLastErrorLine(e.location_get().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)->location_get().first_line, pCall->getName().c_str());
-                                throw ScilabMessage(szError);
-                            }
-                            else
-                            {
-                                throw ScilabMessage();
-                            }
-                        }
+                        //the good one
+                        pCase->getBody()->accept(*this);
                     }
-                    catch (ScilabMessage sm)
+                    catch (const InternalError& ie)
                     {
-                        wostringstream os;
-                        PrintVisitor printMe(os);
-                        (*itExp)->accept(printMe);
-                        //os << std::endl << std::endl;
-                        if (ConfigVariable::getLastErrorFunction() == L"")
-                        {
-                            ConfigVariable::setLastErrorFunction(pCall->getName());
-                        }
+                        pIT->DecreaseRef();
+                        pIT->killMe();
+                        CoverageInstance::stopChrono((void*)&e);
+                        throw ie;
+                    }
 
-                        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;
-                        }
+                    if (e.isBreakable() && pCase->getBody()->isBreak())
+                    {
+                        const_cast<SelectExp*>(&e)->setBreak();
+                        pCase->getBody()->resetBreak();
                     }
-                }
 
-                //don't output Simplevar and empty result
-                if (result_get() != NULL && (!(*itExp)->is_simple_var() || bImplicitCall))
-                {
-                    //symbol::Context::getInstance()->put(symbol::Symbol(L"ans"), *execMe.result_get());
-                    InternalType* pITAns = result_get();
-                    symbol::Context::getInstance()->put(m_pAns, pITAns);
-                    if ((*itExp)->is_verbose() && ConfigVariable::isPromptShow())
+                    if (e.isContinuable() && pCase->getBody()->isContinue())
                     {
-                        //TODO manage multiple returns
-                        scilabWriteW(L" ans  =\n\n");
-                        VariableToString(pITAns, L"ans");
+                        const_cast<SelectExp*>(&e)->setContinue();
+                        pCase->getBody()->resetContinue();
                     }
-                }
 
-                pIT->killMe();
-            }
+                    if (e.isReturnable() && pCase->getBody()->isReturn())
+                    {
+                        const_cast<SelectExp*>(&e)->setReturn();
+                        pCase->getBody()->resetReturn();
+                    }
 
-            if ((&e)->is_breakable() && (*itExp)->is_break())
-            {
-                const_cast<SeqExp *>(&e)->break_set();
-                break;
-            }
+                    pITCase->killMe();
+                    bCase = true;
+                    break;
+                }
 
-            if ((&e)->is_continuable() && (*itExp)->is_continue())
-            {
-                const_cast<SeqExp *>(&e)->continue_set();
-                break;
+                pITCase->killMe();
             }
+        }
+    }
 
-            if ((&e)->is_returnable() && (*itExp)->is_return())
-            {
-                const_cast<SeqExp *>(&e)->return_set();
-                (*itExp)->return_reset();
-                break;
-            }
+    if (bCase == false && e.getDefaultCase() != NULL)
+    {
+        try
+        {
+            //default case
+            e.getDefaultCase()->accept(*this);
         }
-        catch (const ScilabMessage& sm)
+        catch (const InternalError& ie)
         {
-            scilabErrorW(sm.GetErrorMessage().c_str());
-
-            CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
-            if (pCall != NULL)
+            if (pIT)
             {
-                //to print call expression only of it is a macro
-                pCall->name_get().accept(*this);
-
-                if (result_get() != NULL && (result_get()->isMacro() || result_get()->isMacroFile()))
-                {
-                    wostringstream os;
-                    PrintVisitor printMe(os);
-                    pCall->accept(printMe);
-                    //os << std::endl << std::endl;
-                    if (ConfigVariable::getLastErrorFunction() == L"")
-                    {
-                        ConfigVariable::setLastErrorFunction(((InternalType*)result_get())->getAs<Callable>()->getName());
-                    }
-                    throw ScilabMessage(os.str(), 0, (*itExp)->location_get());
-                }
+                pIT->DecreaseRef();
+                pIT->killMe();
             }
-
-            throw ScilabMessage((*itExp)->location_get());
+            CoverageInstance::stopChrono((void*)&e);
+            throw ie;
         }
-        catch (const ScilabError& se)
+
+        if (e.isBreakable() && e.getDefaultCase()->isBreak())
         {
-            // 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""));
-            }
+            const_cast<SelectExp*>(&e)->setBreak();
+            e.getDefaultCase()->resetBreak();
+        }
 
-            CallExp* pCall = dynamic_cast<CallExp*>(*itExp);
-            if (pCall != NULL)
-            {
-                //to print call expression only of it is a macro
-                try
-                {
-                    pCall->name_get().accept(*this);
-                    if (result_get() != NULL && (result_get()->isMacro() || result_get()->isMacroFile()))
-                    {
-                        wostringstream os;
-                        PrintVisitor printMe(os);
-                        pCall->accept(printMe);
-                        //os << std::endl << std::endl;
-                        ConfigVariable::setLastErrorFunction(((InternalType*)result_get())->getAs<Callable>()->getName());
-                        scilabErrorW(se.GetErrorMessage().c_str());
-                        throw ScilabMessage(os.str(), 999, (*itExp)->location_get());
-                    }
-                }
-                catch (ScilabError se2)
-                {
-                    //just to catch exception, do nothing
-                }
-            }
+        if (e.isContinuable() && e.getDefaultCase()->isContinue())
+        {
+            const_cast<SelectExp*>(&e)->setContinue();
+            e.getDefaultCase()->resetContinue();
+        }
 
-            scilabErrorW(se.GetErrorMessage().c_str());
-            scilabErrorW(L"\n");
-            throw ScilabMessage((*itExp)->location_get());
+        if (e.isReturnable() && e.getDefaultCase()->isReturn())
+        {
+            const_cast<SelectExp*>(&e)->setReturn();
+            e.getDefaultCase()->resetReturn();
         }
+    }
+
+    clearResult();
 
-        // If something other than NULL is given to result_set, then that would imply
-        // to make a cleanup in visit(ForExp) for example (e.body_get().accept(*this);)
-        result_set(NULL);
+    if (pIT)
+    {
+        pIT->DecreaseRef();
+        pIT->killMe();
     }
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
 void RunVisitorT<T>::visitprivate(const NotExp &e)
 {
+    CoverageInstance::invokeAndStartChrono((void*)&e);
     /*
       @ or ~ !
-    */
-    e.exp_get().accept(*this);
+      */
+    try
+    {
+        e.getExp().accept(*this);
+    }
+    catch (ScilabException &)
+    {
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
+    }
 
-    InternalType * pValue = result_get();
-    InternalType * pReturn = NULL;
+    types::InternalType * pValue = getResult();
+    types::InternalType * pReturn = NULL;
     if (pValue->neg(pReturn))
     {
         if (pValue != pReturn)
@@ -874,7 +1290,7 @@ void RunVisitorT<T>::visitprivate(const NotExp &e)
             pValue->killMe();
         }
 
-        result_set(pReturn);
+        setResult(pReturn);
     }
     else
     {
@@ -885,35 +1301,47 @@ void RunVisitorT<T>::visitprivate(const NotExp &e)
         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)
         {
-            clean_in_out(in, out);
-            throw ScilabError();
+            cleanInOut(in, out);
+            CoverageInstance::stopChrono((void*)&e);
+            throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
         }
 
-        result_set(out);
-        clean_in(in, out);
+        setResult(out);
+        cleanIn(in, out);
     }
+    CoverageInstance::stopChrono((void*)&e);
 }
 
 template <class T>
 void RunVisitorT<T>::visitprivate(const TransposeExp &e)
 {
-    e.exp_get().accept(*this);
+    CoverageInstance::invokeAndStartChrono((void*)&e);
+    try
+    {
+        e.getExp().accept(*this);
+    }
+    catch (ScilabException &)
+    {
+        CoverageInstance::stopChrono((void*)&e);
+        throw;
+    }
 
-    if (result_getSize() != 1)
+    if (getResultSize() != 1)
     {
-        result_clear();
+        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.location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(szError, 999, e.getLocation());
     }
 
-    InternalType * pValue = result_get();
-    InternalType * pReturn = NULL;
-    const bool bConjug = e.conjugate_get() == TransposeExp::_Conjugate_;
+    types::InternalType * pValue = getResult();
+    types::InternalType * pReturn = NULL;
+    const bool bConjug = e.getConjugate() == TransposeExp::_Conjugate_;
 
     if ((bConjug && pValue->adjoint(pReturn)) || (!bConjug && pValue->transpose(pReturn)))
     {
@@ -922,7 +1350,8 @@ void RunVisitorT<T>::visitprivate(const TransposeExp &e)
             pValue->killMe();
         }
 
-        result_set(pReturn);
+        setResult(pReturn);
+        CoverageInstance::stopChrono((void*)&e);
 
         return;
     }
@@ -935,218 +1364,666 @@ void RunVisitorT<T>::visitprivate(const TransposeExp &e)
         pValue->IncreaseRef();
         in.push_back(pValue);
 
-        Callable::ReturnValue Ret;
+        types::Callable::ReturnValue Ret;
         if (bConjug)
         {
-            Ret = Overload::call(L"%" + result_get()->getShortTypeStr() + L"_t", in, 1, out, this);
+            Ret = Overload::call(L"%" + getResult()->getShortTypeStr() + L"_t", in, 1, out, true);
         }
         else
         {
-            Ret = Overload::call(L"%" + result_get()->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)
         {
-            clean_in_out(in, out);
-            throw ScilabError();
+            cleanInOut(in, out);
+            CoverageInstance::stopChrono((void*)&e);
+            throw InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
         }
 
-        result_set(out);
-        clean_in(in, out);
+        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.args_get();
-    for (std::list<Var *>::const_iterator i = pListVar->vars_get().begin(), end = pListVar->vars_get().end(); i != end; ++i)
+    const exps_t & vars = e.getArgs().getVars();
+    for (const auto var : vars)
     {
-        pVarList->push_back(static_cast<SimpleVar*>(*i)->stack_get());
+        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.returns_get();
-    for (std::list<Var *>::const_iterator i = pListRet->vars_get().begin(), end = pListRet->vars_get().end(); i != end; ++i)
+    const exps_t & rets = e.getReturns().getVars();
+    for (const auto ret : rets)
     {
-        pRetList->push_back(static_cast<SimpleVar*>(*i)->stack_get());
+        pRetList->push_back(ret->getAs<SimpleVar>()->getStack());
     }
 
-    types::Macro *pMacro = new types::Macro(e.name_get().name_get(), *pVarList, *pRetList,
-                                            const_cast<SeqExp&>(static_cast<const SeqExp&>(e.body_get())), L"script");
-    pMacro->setFirstLine(e.location_get().first_line);
-
-    bool bEquals = false;
-    int iFuncProt = ConfigVariable::getFuncprot();
-    if (iFuncProt != 0)
+    types::Macro *pMacro = new types::Macro(e.getSymbol().getName(), *pVarList, *pRetList,
+                                            const_cast<SeqExp&>(static_cast<const SeqExp&>(e.getBody())), L"script");
+    pMacro->setLines(e.getLocation().first_line, e.getLocation().last_line);
+    if (e.getMacro())
     {
-        types::InternalType* pITFunc = symbol::Context::getInstance()->get(((FunctionDec&)e).stack_get());
-        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.name_get().name_get().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.name_get().name_get().c_str());
-        sprintf(pstError, _("It is not possible to redefine the %s primitive this way (see clearfun).\n"), pstFuncName);
+        char* pstFuncName = wide_string_to_UTF8(e.getSymbol().getName().c_str());
+        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.location_get());
+        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.start_get().accept(*this);
-    GenericType* pITStart = static_cast<GenericType*>(result_get());
-    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.location_get());
+        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.step_get().accept(*this);
-    GenericType* pITStep = static_cast<GenericType*>(result_get());
-    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.location_get());
+        CoverageInstance::stopChrono((void*)&e);
+        throw InternalError(szError, 999, e.getLocation());
     }
-    InternalType* piStep = pITStep;
 
-    e.end_get().accept(*this);
-    GenericType* pITEnd = static_cast<GenericType*>(result_get());
-    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.location_get());
+        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
-        result_set(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
-            result_set(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);
+
+    try
+    {
+        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);
+        }
+    }
+    catch (const InternalError& error)
+    {
+        setResult(NULL);
+        cleanInOut(in, out);
+        CoverageInstance::stopChrono((void*)&e);
+        throw error;
+    }
+
+    if (Ret != types::Callable::OK)
+    {
+        setResult(NULL);
+        cleanInOut(in, out);
+        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();
 
-    in.push_back(piStart);
-    if (e.hasExplicitStep())
+    if (pIT->isDouble())
     {
-        // 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 (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
     {
-        // 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);
+        pIT->killMe();
+        yd->killMe();
+        xd->killMe();
+        try
+        {
+            e.getOriginal()->accept(*this);
+        }
+        catch (ScilabException &)
+        {
+            CoverageInstance::stopChrono((void*)&e);
+            throw;
+        }
+        CoverageInstance::stopChrono((void*)&e);
+        return;
     }
 
-    if (Ret != Callable::OK)
+    // 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)
     {
-        clean_in_out(in, out);
-        throw ScilabError();
+        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;
     }
 
-    result_set(out);
-    clean_in(in, out);
+    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>;