Refactor callexp visit 17/14817/4
Calixte DENIZET [Mon, 7 Jul 2014 14:39:40 +0000 (16:39 +0200)]
Change-Id: I8e8ae28c37cc918e3b80d343c9bbcd96933302b9

21 files changed:
scilab/modules/ast/Makefile.am
scilab/modules/ast/Makefile.in
scilab/modules/ast/ast.vcxproj
scilab/modules/ast/ast.vcxproj.filters
scilab/modules/ast/includes/types/arrayof.hxx
scilab/modules/ast/includes/types/callable.hxx
scilab/modules/ast/includes/types/double.hxx
scilab/modules/ast/includes/types/graphichandle.hxx
scilab/modules/ast/includes/types/internal.hxx
scilab/modules/ast/includes/types/list.hxx
scilab/modules/ast/includes/types/mlist.hxx
scilab/modules/ast/includes/types/sparse.hxx
scilab/modules/ast/includes/types/struct.hxx
scilab/modules/ast/includes/types/tlist.hxx
scilab/modules/ast/src/cpp/ast/run_CallExp.cpp
scilab/modules/ast/src/cpp/types/callable.cpp [new file with mode: 0644]
scilab/modules/ast/src/cpp/types/function.cpp
scilab/modules/ast/src/cpp/types/graphichandle.cpp
scilab/modules/ast/src/cpp/types/mlist.cpp
scilab/modules/ast/src/cpp/types/struct.cpp
scilab/modules/ast/src/cpp/types/tlist.cpp

index 71bbe02..bb9d561 100644 (file)
@@ -84,6 +84,7 @@ libsciast_la_SOURCES = \
     src/cpp/types/macro.cpp \
     src/cpp/types/struct.cpp \
     src/cpp/types/macrofile.cpp \
+    src/cpp/types/callable.cpp \
     src/cpp/system_env/dynamic_module.cpp \
     src/cpp/system_env/setenvvar.cpp \
     src/cpp/system_env/sci_home.cpp \
index d52eb7a..6317b8c 100644 (file)
@@ -208,6 +208,7 @@ am__libsciast_la_SOURCES_DIST = src/cpp/ast/runvisitor.cpp \
        src/cpp/types/listundefined.cpp src/cpp/types/string.cpp \
        src/cpp/types/implicitlist.cpp src/cpp/types/macro.cpp \
        src/cpp/types/struct.cpp src/cpp/types/macrofile.cpp \
+       src/cpp/types/callable.cpp \
        src/cpp/system_env/dynamic_module.cpp \
        src/cpp/system_env/setenvvar.cpp \
        src/cpp/system_env/sci_home.cpp \
@@ -296,6 +297,7 @@ am_libsciast_la_OBJECTS = src/cpp/ast/libsciast_la-runvisitor.lo \
        src/cpp/types/libsciast_la-macro.lo \
        src/cpp/types/libsciast_la-struct.lo \
        src/cpp/types/libsciast_la-macrofile.lo \
+       src/cpp/types/libsciast_la-callable.lo \
        src/cpp/system_env/libsciast_la-dynamic_module.lo \
        src/cpp/system_env/libsciast_la-setenvvar.lo \
        src/cpp/system_env/libsciast_la-sci_home.lo \
@@ -732,6 +734,7 @@ libsciast_la_SOURCES = src/cpp/ast/runvisitor.cpp \
        src/cpp/types/listundefined.cpp src/cpp/types/string.cpp \
        src/cpp/types/implicitlist.cpp src/cpp/types/macro.cpp \
        src/cpp/types/struct.cpp src/cpp/types/macrofile.cpp \
+       src/cpp/types/callable.cpp \
        src/cpp/system_env/dynamic_module.cpp \
        src/cpp/system_env/setenvvar.cpp \
        src/cpp/system_env/sci_home.cpp \
@@ -1322,6 +1325,8 @@ src/cpp/types/libsciast_la-struct.lo: src/cpp/types/$(am__dirstamp) \
 src/cpp/types/libsciast_la-macrofile.lo:  \
        src/cpp/types/$(am__dirstamp) \
        src/cpp/types/$(DEPDIR)/$(am__dirstamp)
+src/cpp/types/libsciast_la-callable.lo: src/cpp/types/$(am__dirstamp) \
+       src/cpp/types/$(DEPDIR)/$(am__dirstamp)
 src/cpp/system_env/$(am__dirstamp):
        @$(MKDIR_P) src/cpp/system_env
        @: > src/cpp/system_env/$(am__dirstamp)
@@ -1460,6 +1465,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/system_env/$(DEPDIR)/libsciast_la-warningmode.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-arrayof.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-bool.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-callable.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-cell.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-double.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/cpp/types/$(DEPDIR)/libsciast_la-file.Plo@am__quote@
@@ -2029,6 +2035,13 @@ src/cpp/types/libsciast_la-macrofile.lo: src/cpp/types/macrofile.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/types/libsciast_la-macrofile.lo `test -f 'src/cpp/types/macrofile.cpp' || echo '$(srcdir)/'`src/cpp/types/macrofile.cpp
 
+src/cpp/types/libsciast_la-callable.lo: src/cpp/types/callable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/types/libsciast_la-callable.lo -MD -MP -MF src/cpp/types/$(DEPDIR)/libsciast_la-callable.Tpo -c -o src/cpp/types/libsciast_la-callable.lo `test -f 'src/cpp/types/callable.cpp' || echo '$(srcdir)/'`src/cpp/types/callable.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/types/$(DEPDIR)/libsciast_la-callable.Tpo src/cpp/types/$(DEPDIR)/libsciast_la-callable.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='src/cpp/types/callable.cpp' object='src/cpp/types/libsciast_la-callable.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o src/cpp/types/libsciast_la-callable.lo `test -f 'src/cpp/types/callable.cpp' || echo '$(srcdir)/'`src/cpp/types/callable.cpp
+
 src/cpp/system_env/libsciast_la-dynamic_module.lo: src/cpp/system_env/dynamic_module.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsciast_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT src/cpp/system_env/libsciast_la-dynamic_module.lo -MD -MP -MF src/cpp/system_env/$(DEPDIR)/libsciast_la-dynamic_module.Tpo -c -o src/cpp/system_env/libsciast_la-dynamic_module.lo `test -f 'src/cpp/system_env/dynamic_module.cpp' || echo '$(srcdir)/'`src/cpp/system_env/dynamic_module.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) src/cpp/system_env/$(DEPDIR)/libsciast_la-dynamic_module.Tpo src/cpp/system_env/$(DEPDIR)/libsciast_la-dynamic_module.Plo
index 07919ee..a1a6384 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup Label="ProjectConfigurations">
     <ProjectConfiguration Include="Debug|Win32">
@@ -237,7 +237,6 @@ lib /DEF:"$(ProjectDir)fileio_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <None Include="fileio_Import.def" />
     <None Include="io_Import.def" />
     <None Include="linear_algebra_f_Import.def" />
-    <None Include="localization_Import.def" />
     <None Include="output_stream_Import.def" />
     <None Include="polynomials_f_Import.def" />
     <None Include="threads_Import.def" />
@@ -464,6 +463,7 @@ lib /DEF:"$(ProjectDir)fileio_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
     <ClCompile Include="src\cpp\system_env\warningmode.cpp" />
     <ClCompile Include="src\cpp\types\arrayof.cpp" />
     <ClCompile Include="src\cpp\types\bool.cpp" />
+    <ClCompile Include="src\cpp\types\callable.cpp" />
     <ClCompile Include="src\cpp\types\cell.cpp" />
     <ClCompile Include="src\cpp\types\double.cpp" />
     <ClCompile Include="src\cpp\types\file.cpp" />
@@ -514,4 +514,4 @@ lib /DEF:"$(ProjectDir)fileio_import.def" /SUBSYSTEM:WINDOWS /MACHINE:$(Platform
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 99f96ac..1b6141e 100644 (file)
@@ -59,9 +59,6 @@
     <None Include="core_Import.def">
       <Filter>Libraries Dependencies</Filter>
     </None>
-    <None Include="localization_Import.def">
-      <Filter>Libraries Dependencies</Filter>
-    </None>
     <None Include="elementary_functions_f_Import.def">
       <Filter>Libraries Dependencies</Filter>
     </None>
     <ClCompile Include="src\cpp\types\overload.cpp">
       <Filter>Source Files\types</Filter>
     </ClCompile>
+    <ClCompile Include="src\cpp\types\callable.cpp">
+      <Filter>Source Files\types</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>
\ No newline at end of file
index 2182776..91c741b 100644 (file)
@@ -982,6 +982,47 @@ public :
         return pOut;
     }
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        if (in.size() == 0)
+        {
+            out.push_back(this);
+        }
+        else
+        {
+            InternalType * _out = extract(&in);
+            if (!_out)
+            {
+                std::wostringstream os;
+                os << _W("Invalid index.\n");
+                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
+            }
+            out.push_back(_out);
+        }
+
+        return true;
+    }
+
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return false;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return -1;
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return 1;
+    }
+
     InternalType* extract(typed_list* _pArgs)
     {
         ArrayOf<T>* pOut    = NULL;
index 256c41c..7674769 100644 (file)
@@ -49,6 +49,28 @@ public :
 
     virtual ReturnValue   call(typed_list &in, optional_list &opt, int _iRetCount, typed_list &out, ast::ConstVisitor* execFunc) = 0;
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e);
+
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return true;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return getNbInputArgument();
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return getNbOutputArgument();
+    }
+
     void                  setName(std::wstring _wstName)
     {
         m_wstName = _wstName;
index e75b324..10f0093 100644 (file)
@@ -144,6 +144,18 @@ public :
                : IdDouble;
     }
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        if (isEmpty())
+        {
+            out.push_back(this);
+
+            return true;
+        }
+
+        return ArrayOf<double>::invoke(in, opt, _iRetCount, out, execFunc, e);
+    }
+
     inline bool conjugate(InternalType *& out)
     {
         if (isEmpty() || isIdentity() || !isComplex())
index a822b9c..73e1bdb 100644 (file)
@@ -80,6 +80,8 @@ public :
         return true;
     }
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e);
+
 protected :
     inline ScilabType          getType(void)
     {
index aad774c..a43df8a 100644 (file)
@@ -25,9 +25,15 @@ extern "C"
 #include "dynlib_ast.h"
 }
 
+#include "visitor.hxx" // for invoke
+#include "callexp.hxx"
+#include "localization.hxx"
+#include "scilabexception.hxx"
+
+
 #define bsiz 4096
 
-//#define _SCILAB_DEBUGREF_ 1
+//#define _SCILAB_DEBUGREF_
 #ifdef _SCILAB_DEBUGREF_
 #define DecreaseRef() _decreaseref(__FILE__, __LINE__)
 #define IncreaseRef() _increaseref(__FILE__, __LINE__)
@@ -36,6 +42,13 @@ extern "C"
 
 namespace types
 {
+/*
+** List of types
+*/
+class InternalType;
+typedef std::vector<InternalType *> typed_list;
+typedef std::vector<std::pair<std::wstring, InternalType *> > optional_list;
+
 class EXTERN_AST InternalType
 {
 public :
@@ -169,16 +182,13 @@ public :
 protected :
     InternalType() : m_iRef(0), m_bAllowDelete(true), m_bPrintFromStart(true), m_iSavePrintState(0), m_iRows1PrintState(0), m_iCols1PrintState(0), m_iRows2PrintState(0), m_iCols2PrintState(0)
     {
-
 #ifdef _SCILAB_DEBUGREF_
         std::cout << "new IT =" << (void*)this << std::endl;
 #endif
-
     }
 
 public :
-    virtual                         ~InternalType() { }
-
+    virtual                         ~InternalType() {}
     virtual void                    whoAmI(void)
     {
         std::cout << "types::Inernal";
@@ -203,7 +213,6 @@ public :
     }
     virtual InternalType*           clone(void) = 0;
 
-
 #ifdef _SCILAB_DEBUGREF_
     inline void _killme(const char * f, int l)
     {
@@ -229,6 +238,7 @@ public :
         std::cout << "decref (" << m_iRef << ")=" << (void*)this << " in " << f << " at line " << l << std::endl;
     }
 #else
+
     inline void killMe()
     {
         if (isDeletable())
@@ -296,6 +306,31 @@ public :
         return false;
     }
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        return false;
+    }
+
+    virtual bool isInvokable() const
+    {
+        return false;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return false;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return -1;
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return -1;
+    }
+
     /* return type as string ( double, int, cell, list, ... )*/
     virtual std::wstring            getTypeStr() = 0;
     /* return type as short string ( s, i, ce, l, ... )*/
@@ -517,12 +552,6 @@ protected :
 
 };
 
-/*
-** List of types
-*/
-typedef std::vector<InternalType *> typed_list;
-typedef std::vector<std::pair<std::wstring, InternalType *> > optional_list;
-
 }
 
 #ifdef _SCILAB_DEBUGREF_
index 0c40da4..a72b697 100644 (file)
@@ -67,6 +67,48 @@ public :
 
     InternalType*                   insert(typed_list* _pArgs, InternalType* _pSource);
     std::vector<InternalType*>      extract(typed_list* _pArgs);
+
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        if (in.size() == 0)
+        {
+            out.push_back(this);
+        }
+        else
+        {
+            std::vector<InternalType *> _out = extract(&in);
+            if (_out.empty())
+            {
+                std::wostringstream os;
+                os << _W("Invalid index.\n");
+                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
+            }
+            out.swap(_out);
+        }
+
+        return true;
+    }
+
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return false;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return -1;
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return -1;
+    }
+
     virtual InternalType*           get(const int _iIndex);
     virtual bool                    set(const int _iIndex, InternalType* _pIT);
 
index d6dce46..1396ff2 100644 (file)
@@ -46,6 +46,8 @@ public :
         return false;
     }
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e);
+
 protected :
     MList(MList *_oMListCopyMe) : TList(_oMListCopyMe) {}
 };
index 01941f0..44b4fa8 100644 (file)
@@ -198,6 +198,48 @@ struct EXTERN_AST Sparse : GenericType
 
      */
     InternalType* extract(typed_list* _pArgs);
+
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        if (in.size() == 0)
+        {
+            out.push_back(this);
+        }
+        else
+        {
+            InternalType * _out = extract(&in);
+            if (!_out)
+            {
+                std::wostringstream os;
+                os << _W("Invalid index.\n");
+                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
+            }
+            out.push_back(_out);
+        }
+
+        return true;
+    }
+
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return false;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return -1;
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return 1;
+    }
+
     Sparse* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
 
     /*
@@ -546,6 +588,47 @@ struct EXTERN_AST SparseBool : GenericType
     SparseBool* extract(int _iSeqCount, int* _piSeqCoord, int* _piMaxDim, int* _piDimSize, bool _bAsVector) SPARSE_CONST;
     InternalType* extract(typed_list* _pArgs);
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+    {
+        if (in.size() == 0)
+        {
+            out.push_back(this);
+        }
+        else
+        {
+            InternalType * _out = extract(&in);
+            if (!_out)
+            {
+                std::wostringstream os;
+                os << _W("Invalid index.\n");
+                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
+            }
+            out.push_back(_out);
+        }
+
+        return true;
+    }
+
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    virtual bool hasInvokeOption() const
+    {
+        return false;
+    }
+
+    virtual int getInvokeNbIn()
+    {
+        return -1;
+    }
+
+    virtual int getInvokeNbOut()
+    {
+        return 1;
+    }
+
     SparseBool* getColumnValues(int _iPos)
     {
         return NULL;
index 12f2a83..7f6c3fb 100644 (file)
 #include "arrayof.hxx"
 #include "singlestruct.hxx"
 
+extern "C"
+{
+#include "localization.h"
+}
+
 namespace types
 {
 class EXTERN_AST Struct : public ArrayOf<SingleStruct*>
@@ -118,6 +123,13 @@ public :
     using ArrayOf<SingleStruct *>::extract;
     bool extract(const std::wstring & name, InternalType *& out);
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e);
+
+    virtual int getInvokeNbOut()
+    {
+        return -1;
+    }
+
 private :
     virtual SingleStruct*       getNullValue();
     virtual Struct*             createEmpty(int _iDims, int* _piDims, bool _bComplex = false);
index 42f5ab5..3f54b06 100644 (file)
@@ -54,6 +54,8 @@ public :
     using List::extract; // to avoid this extract to hide extract in list
     bool                            extract(const std::wstring & name, InternalType *& out);
 
+    virtual bool invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e);
+
     bool isFieldExtractionOverloadable() const
     {
         return true;
index 8feb43e..eeb1da2 100644 (file)
 template<class T>
 void RunVisitorT<T>::visitprivate(const CallExp &e)
 {
-    std::list<Exp *>::const_iterator   itExp;
+    std::list<Exp *>::const_iterator itExp;
 
     e.name_get().accept(*this);
-    if (result_get() != NULL && result_get()->isCallable())
+
+    if (result_get() != NULL && result_get()->isInvokable())
     {
         //function call
         types::InternalType* pIT = result_get();
-        types::Callable *pCall = pIT->getAs<types::Callable>();
         types::typed_list out;
         types::typed_list in;
         types::optional_list opt;
@@ -30,7 +30,7 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
         int iRetCount = expected_getSize();
 
         // manage case [a,b]=foo() where foo is defined as a=foo()
-        if (pCall->getNbOutputArgument() != -1 && pCall->getNbOutputArgument() < iRetCount)
+        if (pIT->getInvokeNbOut() != -1 && pIT->getInvokeNbOut() < iRetCount)
         {
             pIT->killMe();
             std::wostringstream os;
@@ -49,10 +49,9 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 if (!pL->is_simple_var())
                 {
                     pIT->killMe();
-                    for (optional_list::const_iterator o = opt.begin(), end = opt.end(); o != end; ++o)
-                    {
-                        o->second->killMe();
-                    }
+                    clean_opt(opt);
+                    clean_in(in, out);
+
                     std::wostringstream os;
                     os << _W("left side of optional parameter must be a variable") << std::endl;
                     throw ast::ScilabError(os.str(), 999, e.location_get());
@@ -63,13 +62,22 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 pR->accept(*this);
                 InternalType* pITR = result_get();
 
-                opt.push_back(std::pair<std::wstring, InternalType*>(pVar->name_get().name_get(), pITR));
-                //in case of macro/macrofile, we have to shift input param
-                //so add NULL item in in list to keep initial order
-                if (pIT->isMacro() || pIT->isMacroFile())
+                if (pIT->hasInvokeOption())
+                {
+                    opt.push_back(std::pair<std::wstring, InternalType*>(pVar->name_get().name_get(), pITR));
+                    //in case of macro/macrofile, we have to shift input param
+                    //so add NULL item in in list to keep initial order
+                    if (pIT->isMacro() || pIT->isMacroFile())
+                    {
+                        in.push_back(NULL);
+                    }
+                }
+                else
                 {
-                    in.push_back(NULL);
+                    pITR->IncreaseRef();
+                    in.push_back(pITR);
                 }
+
                 continue;
             }
 
@@ -82,10 +90,10 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 continue;
             }
 
-            pIT = result_get();
-            if (pIT->isImplicitList())
+            InternalType * pITArg = result_get();
+            if (pITArg->isImplicitList())
             {
-                types::ImplicitList* pIL = pIT->getAs<types::ImplicitList>();
+                types::ImplicitList* pIL = pITArg->getAs<types::ImplicitList>();
                 if (pIL->isComputable() == false)
                 {
                     types::Double* pVal = new types::Double(-1, -1);
@@ -96,7 +104,7 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 {
                     result_set(pIL->extractFullMatrix());
                 }
-                pIT->killMe();
+                pITArg->killMe();
             }
 
             if (is_single_result())
@@ -108,9 +116,9 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
             {
                 for (int i = 0 ; i < result_getSize() ; i++)
                 {
-                    InternalType * pIT = result_get(i);
-                    pIT->IncreaseRef();
-                    in.push_back(pIT);
+                    InternalType * pITArg = result_get(i);
+                    pITArg->IncreaseRef();
+                    in.push_back(pITArg);
                 }
             }
         }
@@ -121,520 +129,54 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
             expected_setSize(iSaveExpectedSize);
             iRetCount = std::max(1, iRetCount);
 
-            //reset previous error before call function
-            ConfigVariable::resetError();
-            //update verbose";" flag
-            ConfigVariable::setVerbose(e.is_verbose());
-            // add line and function name in where
-            ConfigVariable::where_begin(((int)e.location_get().first_line - ConfigVariable::getMacroFirstLines()) + 1, pCall->getName());
-            //call function
-            types::Function::ReturnValue Ret = pCall->call(in, opt, iRetCount, out, this);
-            // remove the last call from where
-            ConfigVariable::where_end();
-            expected_setSize(iSaveExpectedSize);
-            result_clear();
-
-            if (Ret == types::Callable::OK)
+            if (pIT->invoke(in, opt, iRetCount, out, *this, e))
             {
-                if (expected_getSize() == 1 && out.size() == 0) //some function have no returns
+                if (iSaveExpectedSize != -1 && iSaveExpectedSize > out.size())
                 {
-                    if (0 < iRetCount)
-                    {
-                        std::wostringstream os;
-                        os << _W("bad lhs, expected : ") << iRetCount << _W(" returned : ") << out.size() << std::endl;
-                        throw ast::ScilabError(os.str(), 999, e.location_get());
-                    }
+                    std::wostringstream os;
+                    os << _W("bad lhs, expected : ") << iRetCount << _W(" returned : ") << out.size() << std::endl;
+                    throw ast::ScilabError(os.str(), 999, e.location_get());
                 }
 
+                result_clear();
                 result_set(out);
                 clean_in(in, out);
                 clean_opt(opt);
-                pCall->killMe();
-            }
-            else if (Ret == types::Callable::Error)
-            {
-                ConfigVariable::setLastErrorFunction(pCall->getName());
-                ConfigVariable::setLastErrorLine(e.location_get().first_line);
-                throw ast::ScilabError();
-            }
-        }
-        catch (ScilabMessage & sm)
-        {
-            ConfigVariable::where_end();
-            clean_in_out(in, out);
-            clean_opt(opt);
-
-            if (pCall->isMacro() || pCall->isMacroFile())
-            {
-                pCall->killMe();
-                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 ast::ScilabMessage(szError);
+                pIT->killMe();
             }
             else
             {
-                pCall->killMe();
-                throw sm;
+                std::wostringstream os;
+                os << _W("Invalid index.\n");
+                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
             }
         }
-        catch (ScilabError & se)
+        catch (ScilabMessage & sm)
         {
-            ConfigVariable::where_end();
+            result_clear();
             clean_in_out(in, out);
             clean_opt(opt);
-            pCall->killMe();
+            pIT->killMe();
 
-            throw se;
+            throw sm;
         }
         catch (InternalAbort & ia)
         {
-            ConfigVariable::where_end();
+            result_clear();
             clean_in_out(in, out);
             clean_opt(opt);
-            pCall->killMe();
+            pIT->killMe();
 
             throw ia;
         }
-    }
-    else if (result_get() != NULL)
-    {
-        //a(xxx) with a variable, extraction
-
-        //get symbol of variable
-        types::InternalType *pIT = result_get();
-        int iArgDim = static_cast<int>(e.args_get().size());
-        types::InternalType *pOut = NULL;
-        std::vector<types::InternalType*> ResultList;
-
-        //To manage extraction without parameter like SCI()
-        if (iArgDim == 0)
-        {
-            return;
-        }
-        else
-        {
-            //Create list of indexes
-            types::typed_list *pArgs = GetArgumentList(e.args_get());
-
-            switch (pIT->getType())
-            {
-                case types::InternalType::ScilabDouble :
-                    pOut = pIT->getAs<types::Double>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabString :
-                    pOut = pIT->getAs<types::String>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabBool :
-                    pOut = pIT->getAs<types::Bool>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabPolynom :
-                    pOut = pIT->getAs<types::Polynom>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabInt8 :
-                    pOut = pIT->getAs<types::Int8>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabUInt8 :
-                    pOut = pIT->getAs<types::UInt8>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabInt16 :
-                    pOut = pIT->getAs<types::Int16>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabUInt16 :
-                    pOut = pIT->getAs<types::UInt16>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabInt32 :
-                    pOut = pIT->getAs<types::Int32>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabUInt32 :
-                    pOut = pIT->getAs<types::UInt32>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabInt64 :
-                    pOut = pIT->getAs<types::Int64>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabUInt64 :
-                    pOut = pIT->getAs<types::UInt64>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabList :
-                {
-                    ResultList = pIT->getAs<types::List>()->extract(pArgs);
-
-                    switch (ResultList.size())
-                    {
-                        case 0 :
-                        {
-                            result_set(NULL);
-                        }
-                        break;
-                        case 1 :
-                            result_set(ResultList[0]);
-                            break;
-                        default :
-                            for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
-                            {
-                                result_set(i, ResultList[i]);
-                            }
-                            break;
-                    }
-                }
-                break;
-                case InternalType::ScilabTList :
-                {
-                    Function::ReturnValue ret = Function::OK;
-                    bool bCallOverLoad = false;
-                    if (pArgs->size() == 1)
-                    {
-                        types::InternalType* pArg = (*pArgs)[0];
-                        if ( pArg->isDouble() ||
-                                pArg->isInt() ||
-                                pArg->isBool() ||
-                                pArg->isImplicitList() ||
-                                pArg->isColon() ||
-                                pArg->isDollar())
-
-                        {
-                            //call "normal" extract
-                            typed_list iField;
-                            iField.push_back(pArg);
-                            ResultList = pIT->getAs<TList>()->extract(&iField);
-                        }
-                        else if (pArg->isString())
-                        {
-                            //extractStrings
-                            list<wstring> stFields;
-                            String *pString = (*pArgs)[0]->getAs<types::String>();
-                            for (int i = 0 ; i < pString->getSize() ; i++)
-                            {
-                                stFields.push_back(pString->get(i));
-                            }
-
-                            ResultList = pIT->getAs<TList>()->extractStrings(stFields);
-                            if (ResultList.empty())
-                            {
-                                bCallOverLoad = true;
-                            }
-                        }
-                        else
-                        {
-                            bCallOverLoad = true;
-                        }
-                    }
-                    else
-                    {
-                        bCallOverLoad = true;
-                    }
-
-                    if (bCallOverLoad)
-                    {
-                        types::typed_list in;
-
-                        //create input argument list
-
-                        //protect inputs
-                        for (int i = 0 ; i < (int)pArgs->size() ; i++)
-                        {
-                            (*pArgs)[i]->IncreaseRef();
-                            in.push_back((*pArgs)[i]);
-                        }
-
-                        //protect TList
-                        pIT->IncreaseRef();
-                        in.push_back(pIT);
-
-                        try
-                        {
-                            //try to call specific exrtaction function
-                            ret = Overload::call(L"%" + pIT->getAs<TList>()->getShortTypeStr() + L"_e", in, 1, ResultList, this);
-                        }
-                        catch (ast::ScilabError /*&e*/)
-                        {
-                            //if call failed try to call generic extraction function
-                            ret = Overload::call(L"%l_e", in, 1, ResultList, this);
-                        }
-
-                        for (int i = 0 ; i < (int)pArgs->size() ; i++)
-                        {
-                            (*pArgs)[i]->DecreaseRef();
-                        }
-                        pIT->DecreaseRef();
-                    }
-
-                    if (ret == Function::OK)
-                    {
-                        switch (ResultList.size())
-                        {
-                            case 0 :
-                            {
-                                delete pArgs;
-                                std::wostringstream os;
-                                os << _W("Invalid index.\n");
-                                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
-                            }
-                            break;
-                            case 1 :
-                                result_set(ResultList[0]);
-                                break;
-                            default :
-                                for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
-                                {
-                                    result_set(i, ResultList[i]);
-                                }
-                                break;
-                        }
-                    }
-                    else
-                    {
-                        delete pArgs;
-                        throw ast::ScilabError();
-                    }
-                    break;
-                }
-                case InternalType::ScilabMList :
-                {
-                    Function::ReturnValue ret = Function::OK;
-                    bool bCallOverLoad = false;
-                    if (pArgs->size() == 1)
-                    {
-                        types::InternalType* pArg = (*pArgs)[0];
-                        if (pArg->isString())
-                        {
-                            //extractStrings
-                            list<wstring> stFields;
-                            String *pString = (*pArgs)[0]->getAs<types::String>();
-                            for (int i = 0 ; i < pString->getSize() ; i++)
-                            {
-                                stFields.push_back(pString->get(i));
-                            }
-
-                            ResultList = pIT->getAs<MList>()->extractStrings(stFields);
-                            if (ResultList.empty())
-                            {
-                                bCallOverLoad = true;
-                            }
-                        }
-                        else
-                        {
-                            bCallOverLoad = true;
-                        }
-                    }
-                    else
-                    {
-                        bCallOverLoad = true;
-                    }
-
-                    if (bCallOverLoad)
-                    {
-                        types::typed_list in;
-
-                        //create input argument list
-
-                        //protect inputs
-                        for (int i = 0 ; i < (int)pArgs->size() ; i++)
-                        {
-                            (*pArgs)[i]->IncreaseRef();
-                            in.push_back((*pArgs)[i]);
-                        }
-
-                        //protect TList
-                        pIT->IncreaseRef();
-                        in.push_back(pIT);
-
-                        try
-                        {
-                            //try to call specific exrtaction function
-                            ret = Overload::call(L"%" + pIT->getAs<MList>()->getShortTypeStr() + L"_e", in, 1, ResultList, this);
-                        }
-                        catch (ast::ScilabError /*&e*/)
-                        {
-                            //if call failed try to call generic extraction function
-                            ret = Overload::call(L"%l_e", in, 1, ResultList, this);
-                        }
-
-                        for (int i = 0 ; i < (int)pArgs->size() ; i++)
-                        {
-                            (*pArgs)[i]->DecreaseRef();
-                        }
-                        pIT->DecreaseRef();
-                    }
-
-                    if (ret == Function::OK)
-                    {
-                        switch (ResultList.size())
-                        {
-                            case 0 :
-                            {
-                                delete pArgs;
-                                std::wostringstream os;
-                                os << _W("Invalid index.\n");
-                                throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
-                            }
-                            break;
-                            case 1 :
-                                result_set(ResultList[0]);
-                                break;
-                            default :
-                                for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
-                                {
-                                    result_set(i, ResultList[i]);
-                                }
-                                break;
-                        }
-                    }
-                    else
-                    {
-                        delete pArgs;
-                        throw ast::ScilabError();
-                    }
-                    break;
-                }
-                case InternalType::ScilabCell :
-                    pOut = pIT->getAs<Cell>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabSparse :
-                    pOut = pIT->getAs<types::Sparse>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabSparseBool :
-                    pOut = pIT->getAs<types::SparseBool>()->extract(pArgs);
-                    break;
-                case types::InternalType::ScilabStruct :
-                {
-                    types::Struct* pStr = pIT->getAs<types::Struct>();
-                    if (pArgs->size() == 1 && (*pArgs)[0]->isString())
-                    {
-                        //s(["x","xx"])
-                        std::vector<wstring> wstFields;
-                        types::String *pS = (*pArgs)[0]->getAs<types::String>();
-                        for (int i = 0 ; i < pS->getSize() ; i++)
-                        {
-                            wstring wstField(pS->get(i));
-                            if (pStr->exists(wstField))
-                            {
-                                wstFields.push_back(wstField);
-                            }
-                            else
-                            {
-                                delete pArgs;
-                                wchar_t szError[bsiz];
-                                os_swprintf(szError, bsiz, _W("Field \"%ls\" does not exists\n").c_str(), wstField.c_str());
-                                throw ast::ScilabError(szError, 999, (*e.args_get().begin())->location_get());
-                            }
-                        }
-
-                        ResultList = pStr->extractFields(wstFields);
-                        if (ResultList.size() == 1 && ResultList[0]->isList() == false)
-                        {
-                            result_set(ResultList[0]);
-                        }
-                        else if (ResultList.size() == 1 && ResultList[0]->getAs<types::List>()->getSize() == 1)
-                        {
-                            result_set(ResultList[0]->getAs<types::List>()->get(0));
-                        }
-                        else
-                        {
-                            for (int i = 0 ; i < static_cast<int>(ResultList.size()) ; i++)
-                            {
-                                result_set(i, ResultList[i]);
-                            }
-                        }
-                        delete pArgs;
-                        return;
-                    }
-                    else
-                    {
-                        pOut = pIT->getAs<types::Struct>()->extract(pArgs);
-                    }
-                    break;
-                }
-                case types::InternalType::ScilabHandle :
-                {
-                    if (pArgs->size() == 1 && (*pArgs)[0]->isString())
-                    {
-                        //s(["x"])
-                        types::GraphicHandle* pH = pIT->getAs<types::GraphicHandle>();
-                        types::String *pS = (*pArgs)[0]->getAs<types::String>();
-                        typed_list in;
-                        typed_list out;
-                        optional_list opt;
-
-                        in.push_back(pS);
-                        in.push_back(pH);
-
-                        static symbol::Variable* h_e = NULL;
-                        if (h_e == NULL)
-                        {
-                            h_e = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%h_e"));
-                        }
-
-                        Function* pCall = (Function*)symbol::Context::getInstance()->get(h_e);
-                        Callable::ReturnValue ret =  pCall->call(in, opt, 1, out, this);
-                        if (ret == Callable::OK)
-                        {
-                            pOut = out[0];
-                        }
-                    }
-                    else
-                    {
-                        pOut = pIT->getAs<types::GraphicHandle>()->extract(pArgs);
-                    }
-                    break;
-                }
-                default :
-                    break;
-            }
-
-            //clean pArgs return by GetArgumentList
-            for (int iArg = 0 ; iArg < (int)pArgs->size() ; iArg++)
-            {
-                if ((*pArgs)[iArg]->isDeletable())
-                {
-                    delete (*pArgs)[iArg];
-                }
-            }
-            delete pArgs;
-        }
-
-        //List extraction can return multiple items
-        if (pIT->isList() == false && pIT->isTList() == false)
-        {
-            if (pOut == NULL)
-            {
-                // Special case, try to extract from an empty matrix.
-                if (pIT->isDouble() && pIT->getAs<types::Double>()->getSize() == 0)
-                {
-                    pOut = types::Double::Empty();
-                }
-                else
-                {
-                    pIT->killMe();
-                    std::wostringstream os;
-                    os << _W("Invalid index.\n");
-                    //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
-                    throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
-                }
-            }
-            result_set(pOut);
-        }
-        else
-        {
-            if (ResultList.size() == 0)
-            {
-                if (pIT->isList())
-                {
-                    result_set(NULL);
-                }
-                else
-                {
-                    pIT->killMe();
-                    std::wostringstream os;
-                    os << _W("inconsistent row/column dimensions\n");
-                    //os << ((*e.args_get().begin())->location_get()).location_getString() << std::endl;
-                    throw ast::ScilabError(os.str(), 999, (*e.args_get().begin())->location_get());
-                }
-            }
-        }
-
-        if (result_get() != pIT)
+        catch (ScilabError & se)
         {
+            result_clear();
+            clean_in_out(in, out);
+            clean_opt(opt);
             pIT->killMe();
+
+            throw se;
         }
     }
     else
diff --git a/scilab/modules/ast/src/cpp/types/callable.cpp b/scilab/modules/ast/src/cpp/types/callable.cpp
new file mode 100644 (file)
index 0000000..86b6efc
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
+ *
+ *  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 <sstream>
+#include <vector>
+#include "callable.hxx"
+#include "scilabexception.hxx"
+#include "configvariable.hxx"
+
+
+namespace types
+{
+
+bool Callable::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+{
+    //reset previous error before call function
+    ConfigVariable::resetError();
+    //update verbose";" flag
+    ConfigVariable::setVerbose(e.is_verbose());
+    // add line and function name in where
+    ConfigVariable::where_begin(((int)e.location_get().first_line - ConfigVariable::getMacroFirstLines()) + 1, getName());
+    Callable::ReturnValue Ret;
+
+    try
+    {
+        Ret = call(in, opt, _iRetCount, out, &execFunc);
+        ConfigVariable::where_end();
+    }
+    catch (ast::ScilabMessage & sm)
+    {
+        ConfigVariable::where_end();
+        throw sm;
+    }
+    catch (ast::InternalAbort & ia)
+    {
+        ConfigVariable::where_end();
+        throw ia;
+    }
+    catch (ast::ScilabError & se)
+    {
+        ConfigVariable::where_end();
+        throw se;
+    }
+
+    if (Ret == Callable::Error)
+    {
+        ConfigVariable::setLastErrorFunction(getName());
+        ConfigVariable::setLastErrorLine(e.location_get().first_line);
+        throw ast::ScilabError();
+    }
+
+    return true;
+}
+}
index a46dcc2..d5d6bb9 100644 (file)
@@ -91,6 +91,7 @@ Function::~Function()
 
 }
 
+
 Function::ReturnValue Function::call(typed_list &in, optional_list &opt, int _iRetCount, typed_list &out, ast::ConstVisitor* execFunc)
 {
     if (m_pLoadDeps != NULL)
index 5c42009..f43b714 100644 (file)
@@ -14,6 +14,7 @@
 #include "graphichandle.hxx"
 #include "tostring_common.hxx"
 #include "scilabexception.hxx"
+#include "overload.hxx"
 
 extern "C"
 {
@@ -180,4 +181,24 @@ long long* GraphicHandle::allocData(int _iSize)
     return new long long[_iSize];
 }
 
+bool GraphicHandle::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+{
+    if (in.size() == 0)
+    {
+        out.push_back(this);
+    }
+    else if (in.size() == 1 && in[0]->isString())
+    {
+        this->IncreaseRef();
+        in.push_back(this);
+
+        Overload::call(L"%h_e", in, 1, out, &execFunc);
+    }
+    else
+    {
+        return ArrayOf<long long>::invoke(in, opt, _iRetCount, out, execFunc, e);
+    }
+
+    return true;
+}
 }
index e9427df..01fc8cf 100644 (file)
@@ -12,6 +12,8 @@
 
 #include <sstream>
 #include "mlist.hxx"
+#include "callable.hxx"
+#include "overload.hxx"
 
 #ifndef NDEBUG
 #include "inspector.hxx"
 
 namespace types
 {
+bool MList::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+{
+    if (in.size() == 0)
+    {
+        out.push_back(this);
+        return true;
+    }
+    else if (in.size() == 1)
+    {
+        InternalType * arg = in[0];
+        std::vector<InternalType *> _out;
+        if (arg->isString())
+        {
+            std::list<std::wstring> stFields;
+            String * pString = arg->getAs<types::String>();
+            for (int i = 0; i < pString->getSize(); ++i)
+            {
+                stFields.push_back(pString->get(i));
+            }
+
+            _out = extractStrings(stFields);
+        }
+
+        if (!_out.empty())
+        {
+            out.swap(_out);
+            return true;
+        }
+    }
+
+    Callable::ReturnValue ret;
+    this->IncreaseRef();
+    in.push_back(this);
+
+    try
+    {
+        ret = Overload::call(L"%" + getShortTypeStr() + L"_e", in, 1, out, &execFunc);
+    }
+    catch (ast::ScilabError & se)
+    {
+        ret = Overload::call(L"%l_e", in, 1, out, &execFunc);
+    }
+
+    if (ret == Callable::Error)
+    {
+        throw ast::ScilabError();
+    }
+
+    return true;
+}
 }
index 6819cdc..0a27ace 100644 (file)
@@ -153,6 +153,55 @@ bool Struct::extract(const std::wstring & name, InternalType *& out)
     return true;
 }
 
+bool Struct::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+{
+    if (in.size() == 0)
+    {
+        out.push_back(this);
+        return true;
+    }
+    else if (in.size() == 1)
+    {
+        InternalType * arg = in[0];
+        std::vector<InternalType *> _out;
+        if (arg->isString())
+        {
+            std::vector<std::wstring> wstFields;
+            String * pString = arg->getAs<types::String>();
+            for (int i = 0; i < pString->getSize(); ++i)
+            {
+                std::wstring wstField(pString->get(i));
+                if (this->exists(wstField))
+                {
+                    wstFields.push_back(wstField);
+                }
+                else
+                {
+                    wchar_t szError[bsiz];
+                    os_swprintf(szError, bsiz, _W("Field \"%ls\" does not exists\n").c_str(), wstField.c_str());
+                    throw ast::ScilabError(szError, 999, (*e.args_get().begin())->location_get());
+                }
+            }
+
+            _out = extractFields(wstFields);
+            if (_out.size() == 1)
+            {
+                InternalType * pIT = _out[0];
+                if (pIT->isList() && pIT->getAs<List>()->getSize() == 1)
+                {
+                    out.push_back(pIT->getAs<List>()->get(0));
+                    return true;
+                }
+            }
+        }
+
+        out.swap(_out);
+        return true;
+    }
+
+    return ArrayOf<SingleStruct*>::invoke(in, opt, _iRetCount, out, execFunc, e);
+}
+
 bool Struct::set(int _iRows, int _iCols, SingleStruct* _pIT)
 {
     if (_iRows < getRows() && _iCols < getCols())
index 92d8d74..f1f73c5 100644 (file)
@@ -16,6 +16,8 @@
 #include "list.hxx"
 #include "tlist.hxx"
 #include "listundefined.hxx"
+#include "callable.hxx"
+#include "overload.hxx"
 
 #ifndef NDEBUG
 #include "inspector.hxx"
@@ -74,6 +76,61 @@ bool TList::exists(const std::wstring& _sKey)
     return false;
 }
 
+bool TList::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, ast::ConstVisitor & execFunc, const ast::CallExp & e)
+{
+    if (in.size() == 0)
+    {
+        out.push_back(this);
+        return true;
+    }
+    else if (in.size() == 1)
+    {
+        InternalType * arg = in[0];
+        std::vector<InternalType *> _out;
+        if (arg->isDouble() || arg->isInt() || arg->isBool() || arg->isImplicitList() || arg->isColon() || arg->isDollar())
+        {
+            _out = List::extract(&in);
+        }
+        else if (arg->isString())
+        {
+            std::list<std::wstring> stFields;
+            String * pString = arg->getAs<types::String>();
+            for (int i = 0; i < pString->getSize(); ++i)
+            {
+                stFields.push_back(pString->get(i));
+            }
+
+            _out = extractStrings(stFields);
+        }
+
+        if (!_out.empty())
+        {
+            out.swap(_out);
+            return true;
+        }
+    }
+
+    Callable::ReturnValue ret;
+    this->IncreaseRef();
+    in.push_back(this);
+
+    try
+    {
+        ret = Overload::call(L"%" + getShortTypeStr() + L"_e", in, 1, out, &execFunc);
+    }
+    catch (ast::ScilabError & se)
+    {
+        ret = Overload::call(L"%l_e", in, 1, out, &execFunc);
+    }
+
+    if (ret == Callable::Error)
+    {
+        throw ast::ScilabError();
+    }
+
+    return true;
+}
+
 bool TList::extract(const std::wstring & name, InternalType *& out)
 {
     if (exists(name))