Varargout management. Add list comparison. 70/4170/3
Bruno JOFRET [Tue, 7 Jun 2011 10:21:15 +0000 (12:21 +0200)]
Change-Id: I942ac45d58f2a1470f53d572234819e3781a4a93

12 files changed:
scilab/modules/abstractSyntaxTree/includes/run_OpExp.hxx
scilab/modules/abstractSyntaxTree/includes/runvisitor.hxx
scilab/modules/core/tests/unit_tests/varargout.dia.ref [new file with mode: 0644]
scilab/modules/core/tests/unit_tests/varargout.tst [new file with mode: 0644]
scilab/modules/operations/Makefile.am
scilab/modules/operations/Makefile.in
scilab/modules/operations/includes/types_comparison_non_equal.hxx [new file with mode: 0644]
scilab/modules/operations/operations.vcxproj
scilab/modules/operations/operations.vcxproj.filters
scilab/modules/operations/src/cpp/types_comparison_equal.cpp
scilab/modules/operations/src/cpp/types_comparison_non_equal.cpp [new file with mode: 0644]
scilab/modules/types/src/cpp/macro.cpp

index 1d67fc0..8d37d07 100644 (file)
@@ -209,157 +209,22 @@ void visitprivate(const OpExp &e)
             }
         case OpExp::ne :
             {
-                if(TypeL == GenericType::RealDouble && pITL->getAs<Double>()->getSize() == 0)
-                {//[] <> xx
-                    if(TypeR != InternalType::RealDouble)
-                    {
-                        result_set(new Bool(true));
-                        return;
-                    }
-                }
-
-                if(TypeR == GenericType::RealDouble && pITR->getAs<Double>()->getSize() == 0)
-                {//xx <> []
-                    if(TypeL != InternalType::RealDouble)
-                    {
-                        result_set(new Bool(true));
-                        return;
-                    }
-                }
-
-                if(TypeL == GenericType::RealDouble && TypeR == GenericType::RealDouble)
+              try
                 {
-                    Double *pL                 = pITL->getAs<Double>();
-                    Double *pR                 = pITR->getAs<Double>();
-
-                    if(pR->getSize() == 0 && pL->getSize() == 0)
-                    {
-                        pResult = new Bool(false);
-                    }
-                    else if(pL->getSize() == 0  || pR->getSize() == 0)
-                    {
-                        pResult = new Bool(true);
-                    }
-                    else if(pR->getSize() == 1)
-                    {
-                        pResult                                = new Bool(pL->getRows(), pL->getCols());
-                        double dblRef  = pR->getReal(0,0);
-                        for(int i = 0 ; i < pL->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pL->getCols() ; j++)
-                            {
-                                pResult->getAs<types::Bool>()->set(i, j, pL->getReal(i, j) != dblRef);
-                            }
-                        }
-                    }
-                    else if(pL->getSize() == 1)
-                    {
-                        pResult                                = new Bool(pR->getRows(), pR->getCols());
-                        double dblRef  = pL->getReal(0,0);
-                        for(int i = 0 ; i < pR->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pR->getCols() ; j++)
-                            {
-                                pResult->getAs<types::Bool>()->set(i, j, dblRef != pR->getReal(i, j));
-                            }
-                        }
-                    }
-                    else if(pR->getRows() == pL->getRows() && pR->getCols() == pL->getCols())
-                    {
-                        pResult                                = new Bool(pR->getRows(), pR->getCols());
-                        for(int i = 0 ; i < pR->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pR->getCols() ; j++)
-                            {
-                                pResult->getAs<types::Bool>()->set(i, j, pL->getReal(i, j) != pR->getReal(i, j));
-                            }
-                        }
-                    }
-                    else
-                    {
-                        pResult = new Bool(false);
-                    }
-
-                    result_set(pResult);
+                    pResult = GenericComparisonNonEqual(execMeL.result_get(), execMeR.result_get());
                 }
-                else if(TypeL == GenericType::RealString && TypeR == GenericType::RealString)
+                catch (ScilabException *pSE)
                 {
-                    String *pL                 = pITL->getAs<types::String>();
-                    String *pR                 = pITR->getAs<types::String>();
-
-                    if(pL->getSize() == 1)
-                    {
-                        pResult = new Bool(pR->getRows(), pR->getCols());
-
-                        wchar_t* pstL = pL->get()[0];
-                        for(int i = 0 ; i < pR->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pR->getCols() ; j++)
-                            {
-                                wchar_t* pstR = pR->get(i,j);
-                                if(wcscmp(pstL, pstR) == 0)
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,false);
-                                }
-                                else
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,true);
-                                }
-                            }
-                        }
-                    }
-                    else if(pR->getSize() == 1)
-                    {
-                        pResult = new Bool(pL->getRows(), pL->getCols());
-
-                        wchar_t* pstR = pR->get()[0];
-                        for(int i = 0 ; i < pL->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pL->getCols() ; j++)
-                            {
-                                wchar_t* pstL = pL->get(i,j);
-                                if(wcscmp(pstL, pstR) == 0)
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,false);
-                                }
-                                else
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,true);
-                                }
-                            }
-                        }
-                    }
-                    else if(pL->getRows() == pR->getRows() && pL->getCols() == pR->getCols())
-                    {
-                        pResult = new Bool(pL->getRows(), pL->getCols());
-
-                        for(int i = 0 ; i < pL->getRows() ; i++)
-                        {
-                            for(int j = 0 ; j < pL->getCols() ; j++)
-                            {
-                                wchar_t* pstR = pR->get(i,j);
-                                wchar_t* pstL = pL->get(i,j);
-                                if(wcscmp(pstL, pstR) == 0)
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,false);
-                                }
-                                else
-                                {
-                                    pResult->getAs<types::Bool>()->set(i,j,true);
-                                }
-                            }
-                        }
-                    }
-                    else
-                    {
-                        pResult = new Bool(true);
-                    }
-                    result_set(pResult);
+                    pSE->SetErrorLocation(e.right_get().location_get());
+                    throw pSE;
                 }
-                else
+
+                if (pResult == NULL)
                 {
-                    result_set(callOverload(e.oper_get(), &execMeL, &execMeR));
+                    // We did not have any algorithm matching, so we try to call OverLoad
+                    pResult = callOverload(e.oper_get(), &execMeL, &execMeR);
                 }
+                result_set(pResult);
                 break;
             }
         case OpExp::lt :
index 3b1f85b..89c0db9 100644 (file)
@@ -37,6 +37,7 @@
 #include "types_divide.hxx"
 #include "types_power.hxx"
 #include "types_comparison_equal.hxx"
+#include "types_comparison_non_equal.hxx"
 #include "configvariable.hxx"
 #include "overload.hxx"
 #include "scilabexception.hxx"
diff --git a/scilab/modules/core/tests/unit_tests/varargout.dia.ref b/scilab/modules/core/tests/unit_tests/varargout.dia.ref
new file mode 100644 (file)
index 0000000..b69059f
--- /dev/null
@@ -0,0 +1,105 @@
+
+// =============================================================================
+
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+
+// Copyright (C) 2011 - DIGITEO - Bruno JOFRET
+
+//
+
+//  This file is distributed under the same license as the Scilab package.
+
+// =============================================================================
+
+//
+
+// Return 3 values
+
+//
+
+function varargout=__test_function__()
+  varargout(1) = 42;
+  varargout(2) = "value";
+  varargout(3) = list(51);
+endfunction
+// Simple call
+
+__test_function__();
+
+a = __test_function__();
+
+if a <> 42 then bugmes();quit;end;
+
+clear a;
+
+[a,b] = __test_function__();
+
+if a <> 42 then bugmes();quit;end;
+
+if b <> "value" then bugmes();quit;end;
+
+clear a;
+
+clear b;
+
+[a,b,c] = __test_function__();
+
+if a <> 42 then bugmes();quit;end;
+
+if b <> "value" then bugmes();quit;end;
+
+if c <> list(51) then bugmes();quit;end;
+
+clear a;
+
+clear b;
+
+clear c;
+
+// Check call with too much output values.
+
+ierr = execstr("[a,b,c,d] = __test_function__();", "errcatch")
+ierr = 
+
+  999
+
+if ierr == 0 then bugmes();quit;end;
+
+//
+
+// Return a list of 3 elements with second missing.
+
+//
+
+function varargout=__test_function2__()
+  varargout(1) = 42;
+  varargout(3) = "value";
+endfunction
+// Simple call
+
+__test_function2__();
+
+a = __test_function2__();
+
+if a <> 42 then bugmes();quit;end;
+
+clear a;
+
+// varargout(2) is undefined
+
+ierr = execstr("[a,b] = __test_function2__();", "errcatch");
+
+if ierr == 0 then bugmes();quit;end;
+
+//
+
+// varargout is not set : should not work.
+
+//
+
+function varargout=__test_function3__()
+endfunction
+ierr = execstr("__test_function3__();", "errcatch");
+
+if ierr == 0 then bugmes();quit;end;
+
diff --git a/scilab/modules/core/tests/unit_tests/varargout.tst b/scilab/modules/core/tests/unit_tests/varargout.tst
new file mode 100644 (file)
index 0000000..782d034
--- /dev/null
@@ -0,0 +1,68 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2011 - DIGITEO - Bruno JOFRET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+//
+// Return 3 values
+//
+function varargout=__test_function__()
+  varargout(1) = 42;
+  varargout(2) = "value";
+  varargout(3) = list(51);
+endfunction
+
+// Simple call
+__test_function__();
+
+a = __test_function__();
+if a <> 42 then pause, end;
+clear a;
+
+[a,b] = __test_function__();
+if a <> 42 then pause, end;
+if b <> "value" then pause, end;
+clear a;
+clear b;
+
+[a,b,c] = __test_function__();
+if a <> 42 then pause, end;
+if b <> "value" then pause, end;
+if c <> list(51) then pause, end;
+clear a;
+clear b;
+clear c;
+
+// Check call with too much output values.
+ierr = execstr("[a,b,c,d] = __test_function__();", "errcatch")
+if ierr == 0 then pause, end;
+
+//
+// Return a list of 3 elements with second missing.
+//
+function varargout=__test_function2__()
+  varargout(1) = 42;
+  varargout(3) = "value";
+endfunction
+
+// Simple call
+__test_function2__();
+
+a = __test_function2__();
+if a <> 42 then pause, end;
+clear a;
+
+// varargout(2) is undefined
+ierr = execstr("[a,b] = __test_function2__();", "errcatch");
+if ierr == 0 then pause, end;
+
+//
+// varargout is not set : should not work.
+//
+function varargout=__test_function3__()
+endfunction
+
+ierr = execstr("__test_function3__();", "errcatch");
+if ierr == 0 then pause, end;
\ No newline at end of file
index d36212c..6a81397 100644 (file)
@@ -19,7 +19,8 @@ OPERATIONS_CPP_SOURCES =  src/cpp/operations.cpp \
                        src/cpp/types_addition.cpp \
                        src/cpp/types_power.cpp \
                        src/cpp/types_finite.cpp \
-                       src/cpp/types_comparison_equal.cpp
+                       src/cpp/types_comparison_equal.cpp \
+                       src/cpp/types_comparison_non_equal.cpp
 
 pkglib_LTLIBRARIES = libscioperations.la
 
index 620d7ff..78a216f 100644 (file)
@@ -115,7 +115,8 @@ am__objects_2 = libscioperations_la-operations.lo \
        libscioperations_la-types_addition.lo \
        libscioperations_la-types_power.lo \
        libscioperations_la-types_finite.lo \
-       libscioperations_la-types_comparison_equal.lo
+       libscioperations_la-types_comparison_equal.lo \
+       libscioperations_la-types_comparison_non_equal.lo
 am_libscioperations_la_OBJECTS = $(am__objects_1) $(am__objects_2)
 libscioperations_la_OBJECTS = $(am_libscioperations_la_OBJECTS)
 libscioperations_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -425,7 +426,8 @@ OPERATIONS_CPP_SOURCES = src/cpp/operations.cpp \
                        src/cpp/types_addition.cpp \
                        src/cpp/types_power.cpp \
                        src/cpp/types_finite.cpp \
-                       src/cpp/types_comparison_equal.cpp
+                       src/cpp/types_comparison_equal.cpp \
+                       src/cpp/types_comparison_non_equal.cpp
 
 pkglib_LTLIBRARIES = libscioperations.la
 libscioperations_la_LDFLAGS = -version-info $(SCILAB_LIBRARY_VERSION)
@@ -593,6 +595,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-operations_tools.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_addition.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_comparison_equal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_comparison_non_equal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_divide.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_finite.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libscioperations_la-types_multiplication.Plo@am__quote@
@@ -753,6 +756,13 @@ libscioperations_la-types_comparison_equal.lo: src/cpp/types_comparison_equal.cp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libscioperations_la_CXXFLAGS) $(CXXFLAGS) -c -o libscioperations_la-types_comparison_equal.lo `test -f 'src/cpp/types_comparison_equal.cpp' || echo '$(srcdir)/'`src/cpp/types_comparison_equal.cpp
 
+libscioperations_la-types_comparison_non_equal.lo: src/cpp/types_comparison_non_equal.cpp
+@am__fastdepCXX_TRUE@  $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libscioperations_la_CXXFLAGS) $(CXXFLAGS) -MT libscioperations_la-types_comparison_non_equal.lo -MD -MP -MF $(DEPDIR)/libscioperations_la-types_comparison_non_equal.Tpo -c -o libscioperations_la-types_comparison_non_equal.lo `test -f 'src/cpp/types_comparison_non_equal.cpp' || echo '$(srcdir)/'`src/cpp/types_comparison_non_equal.cpp
+@am__fastdepCXX_TRUE@  $(am__mv) $(DEPDIR)/libscioperations_la-types_comparison_non_equal.Tpo $(DEPDIR)/libscioperations_la-types_comparison_non_equal.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='src/cpp/types_comparison_non_equal.cpp' object='libscioperations_la-types_comparison_non_equal.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libscioperations_la_CXXFLAGS) $(CXXFLAGS) -c -o libscioperations_la-types_comparison_non_equal.lo `test -f 'src/cpp/types_comparison_non_equal.cpp' || echo '$(srcdir)/'`src/cpp/types_comparison_non_equal.cpp
+
 mostlyclean-libtool:
        -rm -f *.lo
 
diff --git a/scilab/modules/operations/includes/types_comparison_non_equal.hxx b/scilab/modules/operations/includes/types_comparison_non_equal.hxx
new file mode 100644 (file)
index 0000000..e2f8c10
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - DIGITEO - 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
+ *
+ */
+
+#ifndef __TYPES_COMPARISON_NON_EQUAL_HXX__
+#define __TYPES_COMPARISON_NON_EQUAL_HXX__
+
+#include "dynlib_operations.hxx"
+#include "internal.hxx"
+
+/*
+** Try to find a good algorithm to perform non equal comparison between those 2 datatypes.
+** If none is find, this will return NULL. Overload can then be performed by caller.
+** @param _pLeftOperand, the left comparison operand
+** @param _pRightOperand, the rightt comparison operand
+** @return comparison result
+**
+*/
+EXTERN_OP types::InternalType* GenericComparisonNonEqual(types::InternalType *_pLeftOperand, types::InternalType *_pRightOperand);
+
+#endif /* !__TYPES_COMPARISON_NON_EQUAL_HXX__ */
index a4894aa..cfabbc4 100644 (file)
@@ -203,6 +203,7 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="src\cpp\types_comparison_equal.cpp" />
+    <ClCompile Include="src\cpp\types_comparison_non_equal.cpp" />
     <ClCompile Include="src\c\doublecomplex.c" />
     <ClCompile Include="src\c\matrix_addition.c" />
     <ClCompile Include="src\c\matrix_division.c" />
@@ -232,6 +233,8 @@ lib /DEF:"$(ProjectDir)elementary_functions_f_Import.def" /SUBSYSTEM:WINDOWS /MA
     <ClInclude Include="includes\matrix_transpose.h" />
     <ClInclude Include="includes\operations_tools.h" />
     <ClInclude Include="includes\types_addition.hxx" />
+    <ClInclude Include="includes\types_comparison_equal.hxx" />
+    <ClInclude Include="includes\types_comparison_non_equal.hxx" />
     <ClInclude Include="includes\types_divide.hxx" />
     <ClInclude Include="includes\types_finite.hxx" />
     <ClInclude Include="includes\types_multiplication.hxx" />
index 41a52c6..1ae883a 100644 (file)
@@ -66,6 +66,9 @@
     <ClCompile Include="src\cpp\types_comparison_equal.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="src\cpp\types_comparison_non_equal.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="includes\doublecomplex.h">
     <ClInclude Include="includes\types_substraction.hxx">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="includes\types_comparison_equal.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="includes\types_comparison_non_equal.hxx">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="Localization_Import.def">
index cb93a2c..e12b4ef 100644 (file)
@@ -14,6 +14,7 @@
 #include "bool.hxx"
 #include "double.hxx"
 #include "string.hxx"
+#include "list.hxx"
 
 using namespace types;
 
@@ -257,6 +258,34 @@ InternalType *GenericComparisonEqual(InternalType *_pLeftOperand, InternalType *
     }
 
     /*
+    ** LIST == LIST
+    */
+    if(TypeL == GenericType::RealList && TypeR == GenericType::RealList)
+    {
+        types::List* pLL = _pLeftOperand->getAs<types::List>();
+        types::List* pLR = _pRightOperand->getAs<types::List>();
+
+        if(pLL->getSize() != pLR->getSize())
+        {
+            return new Bool(false);
+        }
+
+        Bool* pB = new Bool(1, pLL->getSize());
+        for(int i = 0 ; i < pLL->getSize() ; i++)
+        {
+            if(*pLL->get(i) == *pLR->get(i))
+            {
+                pB->set(i, true);
+            }
+            else
+            {
+                pB->set(i, false);
+            }
+        }
+        return pB;
+    }
+
+    /*
     ** Default case : Return NULL will Call Overloading.
     */
     return NULL;
diff --git a/scilab/modules/operations/src/cpp/types_comparison_non_equal.cpp b/scilab/modules/operations/src/cpp/types_comparison_non_equal.cpp
new file mode 100644 (file)
index 0000000..68bd811
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011 - DIGITEO - 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
+ *
+ */
+
+#include "types_comparison_non_equal.hxx"
+#include "types_comparison_equal.hxx"
+#include "bool.hxx"
+
+using namespace types;
+
+InternalType *GenericComparisonNonEqual(InternalType *_pLeftOperand, InternalType *_pRightOperand)
+{
+    InternalType* pResult = GenericComparisonEqual(_pLeftOperand, _pRightOperand);
+    if(pResult == NULL)
+    {//to call overloading
+        return NULL;
+    }
+
+    Bool *pB = pResult->getAs<Bool>();
+    if(pB == NULL)
+    {// Oo
+        return NULL;
+    }
+
+    for(int i = 0 ; i < pB->getSize() ; i++)
+    {
+        pB->set(i, pB->get(i) == 0);
+    }
+    return pB;
+}
\ No newline at end of file
index c4a18b7..a6cc6f2 100644 (file)
@@ -82,18 +82,19 @@ namespace types
 
     Callable::ReturnValue Macro::call(typed_list &in, int _iRetCount, typed_list &out, ast::ConstVisitor* execFunc)
     {
+        bool bVarargout = false;
         ReturnValue RetVal = Callable::OK;
         symbol::Context *pContext = symbol::Context::getInstance();
 
+        //open a new scope
+        pContext->scope_begin();
         //check excepted and input/output parameters numbers
         // Scilab Macro can be called with less than prototyped arguments,
         // but not more execpts with varargin
-        // TODO: Manage varargin here
+
+        // varargin management
         if(m_inputArgs->size() > 0 && m_inputArgs->back().name_get() == L"varargin")
         {
-            //open a new scope
-            pContext->scope_begin();
-
             int iVarPos = static_cast<int>(in.size());
             if(iVarPos > static_cast<int>(m_inputArgs->size()) - 1)
             {
@@ -141,13 +142,11 @@ namespace types
                 ostr << std::endl;
             }
             ScierrorW(58, ostr.str().c_str());
+            pContext->scope_end();
                        return Callable::Error;
                }
         else
         {
-            //open a new scope
-            pContext->scope_begin();
-
             //assign value to variable in the new context
             std::list<symbol::Symbol>::const_iterator i;
             typed_list::const_iterator j;
@@ -158,7 +157,20 @@ namespace types
             }
         }
 
-        //common part with or without varargin
+        // varargout management
+        //rules : 
+        // varargout must be alone
+        // varargout is a list
+        // varargout can containt more items than caller need
+        // varargout must containt at leat caller needs
+        if(m_outputArgs->size() == 1 && m_outputArgs->back().name_get() == L"varargout")
+        {
+            bVarargout = true;
+            List* pL = new List();
+            pContext->put(symbol::Symbol(L"varargout"), *pL);
+        }
+
+        //common part with or without varargin/varargout
 
         // Declare nargin & nargout in function context.
         pContext->put(symbol::Symbol(L"nargin"), *new Double(static_cast<double>(in.size())));
@@ -177,20 +189,52 @@ namespace types
                 m_body->returnable_set();
             }
 
-            std::list<symbol::Symbol>::const_iterator i;
-            for (i = m_outputArgs->begin(); i != m_outputArgs->end() && _iRetCount; ++i, --_iRetCount)
+            //varargout management
+            if(bVarargout)
             {
-                InternalType *pIT = pContext->get((*i));
-                if(pIT != NULL)
+                InternalType* pOut = pContext->get(symbol::Symbol(L"varargout"));
+                if(pOut == NULL)
                 {
+                    ScierrorW(999, _W("Invalid index.\n"));
+                    return Callable::Error;
+                }
+
+                List* pVarOut = pOut->getAs<List>();
+                if(pVarOut == NULL || pVarOut->getSize() == 0)
+                {
+                    ScierrorW(999, _W("Invalid index.\n"));
+                    return Callable::Error;
+                }
+
+                for(int i = 0 ; i < Min(pVarOut->getSize(), _iRetCount) ; i++)
+                {
+                    InternalType* pIT = pVarOut->get(i);
+                    if(pIT->isListUndefined())
+                    {
+                        ScierrorW(999, _W("List element number %d is Undefined.\n"), i + 1);
+                        return Callable::Error;
+                    }
+
                     out.push_back(pIT);
                     pIT->IncreaseRef();
                 }
-                else
+            }
+            else
+            {//normal output management
+                std::list<symbol::Symbol>::const_iterator i;
+                for (i = m_outputArgs->begin(); i != m_outputArgs->end() && _iRetCount; ++i, --_iRetCount)
                 {
-                    wchar_t sz[bsiz];
-                    os_swprintf(sz, bsiz, _W("Undefined variable %ls.\n"), (*i).name_get().c_str());
-                    YaspWriteW(sz);
+                    InternalType *pIT = pContext->get((*i));
+                    if(pIT != NULL)
+                    {
+                        out.push_back(pIT);
+                        pIT->IncreaseRef();
+                    }
+                    else
+                    {
+                        ScierrorW(999, _W("Undefined variable %ls.\n"), (*i).name_get().c_str());
+                        return Callable::Error;
+                    }
                 }
             }
         }