somes modifications about UserType 15/16415/1
Cedric Delamarre [Tue, 28 Apr 2015 13:36:25 +0000 (15:36 +0200)]
Change-Id: I43d836cdf2b98ea35d4d0e84e6c9023bea930433

scilab/modules/ast/includes/types/user.hxx
scilab/modules/ast/src/cpp/ast/run_CallExp.hpp
scilab/modules/ast/src/cpp/ast/visitor_common.cpp

index 693062b..68050b4 100644 (file)
@@ -76,15 +76,15 @@ public :
         return NULL;
     }
 
-    // extraction by field
+    // this methode is called to perform an extraction by field. ie : a = myUserType.myfield
     // name is the field name
     // out contain extraction of field
-    virtual bool            extract(const std::wstring & /*name*/, InternalType *& /*out*/)
+    virtual bool          extract(const std::wstring & /*name*/, InternalType *& /*out*/)
     {
         return false;
     }
 
-    // extraction by value
+    // extraction by value, this methode can be only called by "invoke" methode below.
     // _pArs is a list of scilab types:: of where we want to extract
     // return all element extracted, in case when multiple elements returned
     // these elements must be stored in a types::List
@@ -93,10 +93,40 @@ public :
         return NULL;
     }
 
+    // if return false , Scilab will never call "invoke" method
+    virtual bool isInvokable() const
+    {
+        return true;
+    }
+
+    // invoke method is called when a UserType is called with "(...)" ie : a = myUserType(...)
+    // This implementation allow the use of extract method above, but it can be overloaded.
+    // Inputs :
+    //  in          : contain input arguments myUserType(arg1,arg2,...)
+    //  opt         : contain optional input arguments myUserType(arg1=..., arg2=..., ...)
+    //  _iRetCount  : is the number of output arguments (ie : [a,b] = myUserType(...), _iRetCount = 2)
+    //  out         : after "invoke" execution, will contain results
+    //  execFunc    : is used in case of macro call : Overload::call(L"A_Macro", in, _iRetCount, out, execFunc);
+    //  e           : Generally used to return the Location when thowing an error. ie : throw ast::ScilabError(L"error message", 999, e.getLocation());
+    // Outputs :
+    // if false, Scilab will call the macro %UserType_e,where UserType is the string return by the methode getShortTypeStr()
+    // if true, Scilab will set each elements of out in Scilab variables
+    virtual bool invoke(types::typed_list & in, types::optional_list & /*opt*/, int /*_iRetCount*/, types::typed_list & out, ast::ConstVisitor & /*execFunc*/, const ast::Exp & /*e*/)
+    {
+        InternalType* pIT = extract(&in);
+        if (pIT)
+        {
+            out.push_back(pIT);
+            return true;
+        }
+
+        return false;
+    }
+
     // used to compute the iterator in scilab loop "for"
     // when type is a two dimensions array
     // _iPos is the column position
-    virtual GenericType*    getColumnValues(int /*_iPos*/)
+    virtual GenericType*  getColumnValues(int /*_iPos*/)
     {
         return NULL;
     }
index 9386405..1708b62 100644 (file)
@@ -17,11 +17,11 @@ template<class T>
 void RunVisitorT<T>::visitprivate(const CallExp &e)
 {
     e.getName().accept(*this);
+    types::InternalType* pIT = getResult();
 
-    if (getResult() != NULL && getResult()->isInvokable())
+    if (pIT != NULL)
     {
         //function call
-        types::InternalType* pIT = getResult();
         types::typed_list out;
         types::typed_list in;
         types::optional_list opt;
@@ -179,7 +179,23 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                     }
                 }
 
-                if (pIT->invoke(in, opt, iRetCount, out, *this, e))
+                bool ret = false;
+                if(pIT->isInvokable() == false)
+                {
+                    // call overload
+                    ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, this);
+                }
+                else
+                {
+                    ret = pIT->invoke(in, opt, iRetCount, out, *this, e);
+                    if(ret == false && pIT->isUserType())
+                    {
+                        // call overload
+                        ret = Overload::call(L"%" + pIT->getShortTypeStr() + L"_e", in, iRetCount, out, this);
+                    }
+                }
+
+                if (ret)
                 {
                     if (iSaveExpectedSize != -1 && iSaveExpectedSize > out.size())
                     {
@@ -293,13 +309,6 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
             throw se;
         }
     }
-    else
-    {
-        //result == NULL ,variable doesn't exist :(
-        // Sould never be in this case
-        // In worst case variable pointing to function does not exists
-        // visitprivate(SimpleVar) will throw the right exception.
-    }
 }
 
 template<class T>
index 0bad992..5dc832e 100644 (file)
@@ -2356,6 +2356,20 @@ InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType*
         }
         else if (_pVar->isUserType())
         {
+            for (int i = 0; i < _pArgs->size(); i++)
+            {
+                if ((*_pArgs)[i]->isImplicitList())
+                {
+                    types::ImplicitList* pIL = (*_pArgs)[i]->getAs<types::ImplicitList>();
+                    if (pIL->isComputable())
+                    {
+                        InternalType* pIT = pIL->extractFullMatrix();
+                        (*_pArgs)[i]->killMe();
+                        (*_pArgs)[i] = pIT;
+                    }
+                }
+            }
+
             pRet = _pVar->getAs<UserType>()->insert(_pArgs, _pInsert);
             if (pRet == NULL)
             {