* Bug 16191 fixed: now mode(0) and mode(1) are really compact.
[scilab.git] / scilab / modules / ast / src / cpp / ast / runvisitor.cpp
index e8e71af..dc7d63d 100644 (file)
@@ -41,6 +41,7 @@
 #include "macrofile.hxx"
 #include "macro.hxx"
 #include "cell.hxx"
+#include "listinsert.hxx"
 #include "filemanager_interface.h"
 
 #include "runner.hxx"
@@ -125,7 +126,10 @@ void RunVisitorT<T>::visitprivate(const SimpleVar & e)
             ostr << L"(" << pI->getRef() << L")";
 #endif
             ostr << std::endl;
-            ostr << std::endl;
+            if (ConfigVariable::isPrintCompact() == false)
+            {
+                ostr << std::endl;                
+            }
             scilabWriteW(ostr.str().c_str());
             std::wostringstream ostrName;
             ostrName << e.getSymbol().getName();
@@ -425,7 +429,7 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
 
         try
         {
-            Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, this);
+            Ret = Overload::call(L"%" + stType + L"_e", in, 1, out, true);
         }
         catch (const InternalError& ie)
         {
@@ -435,7 +439,7 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
                 //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, this);
+                    Ret = Overload::call(L"%" + stType.substr(0, 8) + L"_e", in, 1, out, true);
                 }
                 else
                 {
@@ -448,7 +452,7 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
                 // TList or Mlist
                 if (pValue->isList())
                 {
-                    Ret = Overload::call(L"%l_e", in, 1, out, this);
+                    Ret = Overload::call(L"%l_e", in, 1, out, true);
                 }
                 else
                 {
@@ -512,15 +516,7 @@ void RunVisitorT<T>::visitprivate(const IfExp  &e)
         }
         else if (e.hasElse())
         {
-            const ast::Exp & _else = e.getElse();
-            if (_else.isCommentExp())
-            {
-                CoverageInstance::invoke(_else);
-            }
-            else
-            {
-                e.getElse().accept(*this);
-            }
+            e.getElse().accept(*this);
         }
     }
     catch (ScilabException &)
@@ -529,31 +525,37 @@ void RunVisitorT<T>::visitprivate(const IfExp  &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);
@@ -585,6 +587,8 @@ void RunVisitorT<T>::visitprivate(const WhileExp  &e)
     while (pIT->isTrue())
     {
         pIT->killMe();
+        setResult(NULL);
+
         try
         {
             e.getBody().accept(*this);
@@ -901,15 +905,9 @@ void RunVisitorT<T>::visitprivate(const ReturnExp &e)
     {
         if (ConfigVariable::getPauseLevel() != 0 && symbol::Context::getInstance()->getScopeLevel() == ConfigVariable::getActivePauseLevel())
         {
-            if (ConfigVariable::getEnableDebug() == true)
-            {
-                sciprint(_("%s: function is disabled in debug mode.\n"), "resume");
-                CoverageInstance::stopChrono((void*)&e);
-                return;
-            }
-
             //return or resume
             ConfigVariable::DecreasePauseLevel();
+            ConfigVariable::macroFirstLine_end();
             CoverageInstance::stopChrono((void*)&e);
             return;
         }
@@ -927,7 +925,7 @@ void RunVisitorT<T>::visitprivate(const ReturnExp &e)
             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 values
+        //in case of CallExp, we can return only one value
         int iSaveExpectedSize = getExpectedSize();
         setExpectedSize(1);
         try
@@ -1303,7 +1301,7 @@ void RunVisitorT<T>::visitprivate(const NotExp &e)
         pValue->IncreaseRef();
         in.push_back(pValue);
 
-        types::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 != types::Callable::OK)
         {
@@ -1369,11 +1367,11 @@ void RunVisitorT<T>::visitprivate(const TransposeExp &e)
         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 != types::Callable::OK)
@@ -1421,6 +1419,10 @@ void RunVisitorT<T>::visitprivate(const FunctionDec & e)
     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())
+    {
+        pMacro->setFileName(e.getMacro()->getFileName());
+    }
 
     if (ctx->isprotected(symbol::Symbol(pMacro->getName())))
     {
@@ -1461,18 +1463,32 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
         CoverageInstance::stopChrono((void*)&e);
         throw;
     }
-    types::GenericType* pITStart = static_cast<types::GenericType*>(getResult());
-    if ((pITStart->getSize() != 1 || (pITStart->isDouble() && pITStart->getAs<types::Double>()->isComplex())) &&
-            pITStart->isList() == false) // list case => call overload
+
+    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
     {
-        pITStart->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"':'", 1);
+        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());
     }
-    types::InternalType * piStart = pITStart;
 
     try
     {
@@ -1483,20 +1499,26 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
         CoverageInstance::stopChrono((void*)&e);
         throw;
     }
-    types::GenericType* pITStep = static_cast<types::GenericType*>(getResult());
+
+    types::InternalType* pITStep = getResult();
+    types::GenericType* pStep = static_cast<types::GenericType*>(pITStep);
     setResult(NULL);
-    if ((pITStep->getSize() != 1 || (pITStep->isDouble() && pITStep->getAs<types::Double>()->isComplex())) &&
-            pITStep->isList() == false) // list case => call overload
+    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);
         CoverageInstance::stopChrono((void*)&e);
         throw InternalError(szError, 999, e.getLocation());
     }
-    types::InternalType* piStep = pITStep;
 
     try
     {
@@ -1508,21 +1530,26 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
         throw;
     }
 
-    types::GenericType* pITEnd = static_cast<types::GenericType*>(getResult());
+    types::InternalType* pITEnd = getResult();
+    types::GenericType* pEnd = static_cast<types::GenericType*>(pITEnd);
     setResult(NULL);
-    if ((pITEnd->getSize() != 1 || (pITEnd->isDouble() && pITEnd->getAs<types::Double>()->isComplex())) &&
-            pITEnd->isList() == false) // list case => call overload
+    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);
+        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());
     }
-    types::InternalType* piEnd = pITEnd;
 
     ////check if implicitlist is 1:$ to replace by ':'
     //if (piStart->isDouble() && piStep->isDouble() && piEnd->isPoly())
@@ -1540,28 +1567,28 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
 
     //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 types::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 types::ImplicitList(piStart, piStep, piEnd));
+            setResult(new types::ImplicitList(pStart, pStep, pEnd));
             CoverageInstance::stopChrono((void*)&e);
             return;
         }
@@ -1572,8 +1599,8 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
     types::typed_list in;
     types::typed_list out;
 
-    piStart->IncreaseRef();
-    in.push_back(piStart);
+    pStart->IncreaseRef();
+    in.push_back(pStart);
 
     try
     {
@@ -1581,20 +1608,20 @@ void RunVisitorT<T>::visitprivate(const ListExp &e)
         {
             // 1:2:4
             //call overload %typeStart_b_typeStep
-            piStep->IncreaseRef();
-            in.push_back(piStep);
-            piEnd->IncreaseRef();
-            in.push_back(piEnd);
-            Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piStep->getShortTypeStr(), in, 1, out, true);
+            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
-            piStep->killMe();
-            piEnd->IncreaseRef();
-            in.push_back(piEnd);
-            Ret = Overload::call(L"%" + piStart->getShortTypeStr() + L"_b_" + piEnd->getShortTypeStr(), in, 1, out, true);
+            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)
@@ -1860,52 +1887,39 @@ void RunVisitorT<T>::visitprivate(const DAXPYExp &e)
         return;
     }
 
-    if (ad && xd && yd)
-    {
-        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;
-        }
-    }
-
-    if (yd)
-    {
-        yd->killMe();
-    }
-
-    if (xd)
+    // 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;
     }
-
-    if (ad)
+    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);
@@ -1937,9 +1951,16 @@ void RunVisitorT<T>::visitprivate(const TryCatchExp  &e)
         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 */)
         {
@@ -1972,11 +1993,17 @@ void RunVisitorT<T>::visitprivate(const TryCatchExp  &e)
         ConfigVariable::setSilentError(oldVal);
         //to lock lasterror
         ConfigVariable::setLastErrorCall();
-        // reset call stack filled when error occured
+        // 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 &)
         {