Scilab User Type. 19/15119/13
Cedric Delamarre [Thu, 28 Aug 2014 13:09:06 +0000 (15:09 +0200)]
exec(SCI+"/modules/scicos/tests/unit_tests/scicos_new.tst");
blk = BIGSOM_f("define");
blk.doc = "toto"
a.b = blk
a.b.doc = "tutu"
a.b.doc.c = 5

Change-Id: I5c9d6e0894d8ba99f5973d4dac76e21761b8f82b

20 files changed:
scilab/modules/ast/includes/types/container.hxx
scilab/modules/ast/includes/types/internal.hxx
scilab/modules/ast/includes/types/list.hxx
scilab/modules/ast/includes/types/pointer.hxx
scilab/modules/ast/includes/types/sparse.hxx
scilab/modules/ast/includes/types/tlist.hxx
scilab/modules/ast/includes/types/types.hxx
scilab/modules/ast/includes/types/user.hxx
scilab/modules/ast/src/cpp/ast/run_CallExp.cpp
scilab/modules/ast/src/cpp/ast/runvisitor.cpp
scilab/modules/ast/src/cpp/ast/visitor_common.cpp
scilab/modules/ast/src/cpp/types/list.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
scilab/modules/ast/src/cpp/types/types_tools.cpp
scilab/modules/data_structures/sci_gateway/cpp/sci_getfield.cpp
scilab/modules/scicos/src/cpp/view_scilab/BaseAdapter.hxx
scilab/modules/scicos/src/cpp/view_scilab/BlockAdapter.cpp
scilab/modules/types/sci_gateway/cpp/sci_usertype.cpp

index 33c8546..c619d46 100644 (file)
@@ -36,7 +36,7 @@ public :
         return true;
     }
 
-    virtual ScilabType        getType(void)
+    virtual ScilabType      getType(void)
     {
         return ScilabContainer;
     }
index 59bd820..21b9dc6 100644 (file)
@@ -296,11 +296,6 @@ public :
         return transpose(out);
     }
 
-    virtual bool extract(const std::wstring & /*name*/, InternalType *& /*out*/)
-    {
-        return false;
-    }
-
     virtual bool isFieldExtractionOverloadable() const
     {
         return false;
@@ -528,6 +523,10 @@ public :
     {
         return false;
     }
+    virtual bool                    isUserType(void)
+    {
+        return false;
+    }
 
     void clearPrintState()
     {
index 242e1b5..75d148f 100644 (file)
@@ -56,8 +56,6 @@ public :
     */
     InternalType*                   clone();
 
-    GenericType*                    getColumnValues(int _iPos);
-
     bool                            toString(std::wostringstream& ostr);
 
     bool                            isList()
@@ -66,7 +64,7 @@ public :
     }
 
     InternalType*                   insert(typed_list* _pArgs, InternalType* _pSource);
-    std::vector<InternalType*>      extract(typed_list* _pArgs);
+    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*/)
     {
@@ -76,8 +74,13 @@ public :
         }
         else
         {
-            std::vector<InternalType *> _out = extract(&in);
-            out.swap(_out);
+            InternalType * _out = extract(&in);
+            List* pList = _out->getAs<types::List>();
+            for (int i = 0; i < pList->getSize(); i++)
+            {
+                out.push_back(pList->get(i));
+            }
+            delete pList;
         }
 
         return true;
index 093a942..d017d8f 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-*  Copyright (C) 202 - Scilab Enterprises - Antoine ELIAS
+*  Copyright (C) 2012 - Scilab Enterprises - Antoine ELIAS
 *
 *  This file must be used under the terms of the CeCILL.
 *  This source file is licensed as described in the file COPYING, which
 
 #include "user.hxx"
 
-
 namespace types
 {
-class Pointer : public User<Pointer>
+class Pointer : public UserType
 {
 public :
     Pointer()
@@ -33,9 +32,19 @@ public :
 
     virtual ~Pointer() {}
 
-    Pointer* getAsPointer()
+    bool hasToString()
+    {
+        return false;
+    }
+
+    std::wstring getTypeStr()
+    {
+        return L"pointer";
+    }
+
+    std::wstring getShortTypeStr()
     {
-        return this;
+        return L"p";
     }
 
     bool isPointer(void)
@@ -50,7 +59,7 @@ public :
 
     InternalType* clone()
     {
-        return new Pointer(get());
+        return new Pointer(m_pvData);
     }
 
     void* get()
index 5b18058..d350494 100644 (file)
@@ -125,11 +125,6 @@ struct EXTERN_AST Sparse : GenericType
     **/
     bool zero_set();
 
-    Sparse* getColumnValues(int /*_iPos*/)
-    {
-        return NULL;
-    }
-
     /*
       Config management and GenericType methods overrides
     */
@@ -635,11 +630,6 @@ struct EXTERN_AST SparseBool : GenericType
         return 1;
     }
 
-    SparseBool* getColumnValues(int /*_iPos*/)
-    {
-        return NULL;
-    }
-
     bool transpose(InternalType *& out)
     {
         out = new SparseBool(new BoolSparse_t(matrixBool->transpose()));
index 3f54b06..38ecda5 100644 (file)
@@ -61,7 +61,7 @@ public :
         return true;
     }
 
-    std::vector<InternalType*>      extractStrings(const std::list<std::wstring>& _stFields);
+    InternalType*                   extractStrings(const std::list<std::wstring>& _stFields);
 
     /* return type as string ( double, int, cell, list, ... )*/
     virtual std::wstring            getTypeStr();
index 333ef80..e99515e 100644 (file)
@@ -63,27 +63,27 @@ public :
     }
 
     /*commun functions*/
-    inline int                         getCols()
+    inline int                  getCols()
     {
         return m_iCols;
     }
 
-    inline int                         getRows()
+    inline int                  getRows()
     {
         return m_iRows;
     }
 
-    inline int                         getSize()
+    inline int                  getSize()
     {
         return m_iSize;
     }
 
-    inline int                         getDims()
+    inline int                  getDims()
     {
         return m_iDims;
     }
 
-    inline int*                        getDimsArray()
+    inline int*                 getDimsArray()
     {
         return m_piDims;
     }
@@ -92,13 +92,15 @@ public :
 
     std::wstring                DimToString();
 
-    inline bool                        isGenericType()
+    inline bool                 isGenericType()
     {
         return true;
     }
 
-    /* FIXME : should be : virtual GenericType*        get(int _iPos) = 0; */
-    virtual GenericType*        getColumnValues(int _iPos) = 0;
+    virtual GenericType*        getColumnValues(int /*_iPos*/)
+    {
+        return NULL;
+    }
 
     bool                        isIdentity(void);
     virtual bool                isAssignable(void)
@@ -106,7 +108,7 @@ public :
         return true;
     }
 
-    virtual ScilabType            getType(void)
+    virtual ScilabType          getType(void)
     {
         return ScilabGeneric;
     }
@@ -127,40 +129,41 @@ public :
         return NULL;
     }
 
-    virtual bool                resize(int* _piDims, int _iDims)
+    virtual bool                resize(int* /*_piDims*/, int /*_iDims*/)
     {
-        // silent unused parameters warnings
-        (void) _piDims;
-        (void) _iDims;
-
         return false;
     }
-    virtual bool                resize(int _iNewRows, int _iNewCols)
-    {
-        // silent unused parameters warnings
-        (void) _iNewRows;
-        (void) _iNewCols;
 
+    virtual bool                resize(int /*_iNewRows*/, int /*_iNewCols*/)
+    {
         return false;
     }
 
-    virtual bool                reshape(int* _piDims, int _iDims)
+    virtual bool                reshape(int* /*_piDims*/, int /*_iDims*/)
     {
-        // silent unused parameters warnings
-        (void) _piDims;
-        (void) _iDims;
+        return false;
+    }
 
+    virtual bool                reshape(int /*_iNewRows*/, int /*_iNewCols*/)
+    {
         return false;
     }
-    virtual bool                reshape(int _iNewRows, int _iNewCols)
+
+    virtual InternalType*       insert(typed_list* /*_pArgs*/, InternalType* /*_pSource*/)
     {
-        // silent unused parameters warnings
-        (void) _iNewRows;
-        (void) _iNewCols;
+        return NULL;
+    }
 
+    virtual bool                extract(const std::wstring & /*name*/, InternalType *& /*out*/)
+    {
         return false;
     }
 
+    virtual InternalType*       extract(typed_list* /*_pArgs*/)
+    {
+        return NULL;
+    }
+
 };
 }
 #endif /* !__TYPES_HXX__ */
index da06657..86ca492 100644 (file)
@@ -1,6 +1,7 @@
 /*
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
+*  Copyright (C) 2014 - Scilab Enterprises - Cedric Delamarre
 *
 *  This file must be used under the terms of the CeCILL.
 *  This source file is licensed as described in the file COPYING, which
 
 namespace types
 {
-template <typename T>
-class User : public InternalType
+class UserType : public GenericType
 {
 public :
-    User() {}
-    virtual                    ~User() {}
-    T*                      getAsUserType()
-    {
-        return this;
-    }
-    //non virtual function to prevent overriding in user derived class
+    UserType() {}
+    virtual ~UserType() {}
+
+    /*** non virtual function to prevent overriding in user derived class ***/
+
     inline ScilabType       getType(void)
     {
         return ScilabUserType;
     }
+
     inline ScilabId         getId(void)
     {
         return IdUserType;
     }
 
-    /*
-    ** User will be asked to implement the following methods
-    ** in order Scilab engine to manage correctly this user type
-    */
-public :
-    virtual bool            toString(std::wostringstream& ostr)
+    bool                    isUserType(void)
     {
-        ostr << L"";
         return true;
     }
-    std::wstring            getTypeStr()
+
+public :
+    /*** User will be asked to implement the following methods      ***/
+    /*** in order Scilab engine to manage correctly this user type  ***/
+
+    std::wstring    getTypeStr() = 0;
+    std::wstring    getShortTypeStr() = 0;
+    InternalType*   clone() = 0;
+
+public :
+    /*** User can overload these methode ***/
+    /*** all methode not overloaded will call scilab overload       ***/
+
+    // hasToString return false so scilab will call overload %..._p
+    // and toString method is useless
+    // if user overload hasToString for return true, he must overload toString method
+    // bool toString(std::wostringstream& ostr)
+    virtual bool    hasToString()
+    {
+        return false;
+    }
+
+    // insertion by value
+    // _pArs is a list of scilab types:: of where we want to extract
+    // _pSource is what we wan to insert
+    virtual InternalType*   insert(typed_list* /*_pArgs*/, InternalType* /*_pSource*/)
+    {
+        return NULL;
+    }
+
+    // extraction by field
+    // name is the field name
+    // out contain extraction of field
+    virtual bool            extract(const std::wstring & /*name*/, InternalType *& /*out*/)
     {
-        return L"pointer";
+        return false;
     }
-    std::wstring            getShortTypeStr()
+
+    // extraction by value
+    // _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
+    virtual InternalType*   extract(typed_list* /*_pArgs*/)
     {
-        return L"p";
+        return NULL;
     }
-    InternalType*           clone()
+
+    // 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*/)
     {
-        return new User();
+        return NULL;
     }
+
 };
 }
 
index 3c7bc71..87e86f6 100644 (file)
@@ -144,11 +144,25 @@ void RunVisitorT<T>::visitprivate(const CallExp &e)
                 cleanIn(in, out);
                 cleanOpt(opt);
 
+
                 // In case a.b(), getResult contain pIT ("b").
                 // If out == pIT, do not delete it.
                 if (getResult() != pIT)
                 {
+                    // protect element of out in case where
+                    // out contain elements of pIT
+                    for (int i = 0; i < out.size(); i++)
+                    {
+                        out[i]->IncreaseRef();
+                    }
+
                     pIT->killMe();
+
+                    // unprotect
+                    for (int i = 0; i < out.size(); i++)
+                    {
+                        out[i]->DecreaseRef();
+                    }
                 }
             }
             else
index 5d3f8ca..16a6c6c 100644 (file)
@@ -139,11 +139,14 @@ void RunVisitorT<T>::visitprivate(const FieldExp &e)
     std::wstring wstField = psvRightMember->getSymbol().getName();
     InternalType * pValue = getResult();
     InternalType * pReturn = NULL;
-    bool ok;
+    bool ok = false;
 
     try
     {
-        ok = pValue->extract(wstField, pReturn);
+        if (pValue->isGenericType())
+        {
+            ok = pValue->getAs<GenericType>()->extract(wstField, pReturn);
+        }
     }
     catch (std::wstring & err)
     {
@@ -348,7 +351,7 @@ void RunVisitorT<T>::visitprivate(const ForExp  &e)
         e.getBody().isReturnable();
     }
 
-    if (getResult()->isImplicitList())
+    if (pIT->isImplicitList())
     {
         ImplicitList* pVar = pIT->getAs<ImplicitList>();
         for (int i = 0; i < pVar->getSize(); ++i)
@@ -377,7 +380,7 @@ void RunVisitorT<T>::visitprivate(const ForExp  &e)
             }
         }
     }
-    else if (getResult()->isList())
+    else if (pIT->isList())
     {
         List* pL = pIT->getAs<List>();
         const int size = pL->getSize();
@@ -406,7 +409,7 @@ void RunVisitorT<T>::visitprivate(const ForExp  &e)
             }
         }
     }
-    else
+    else if (pIT->isGenericType())
     {
         //Matrix i = [1,3,2,6] or other type
         GenericType* pVar = pIT->getAs<GenericType>();
@@ -414,13 +417,20 @@ void RunVisitorT<T>::visitprivate(const ForExp  &e)
         {
             pIT->DecreaseRef();
             pIT->killMe();
-
             throw ScilabError(_W("for expression can only manage 1 or 2 dimensions variables\n"), 999, e.getVardec().getLocation());
         }
 
         for (int i = 0; i < pVar->getCols(); i++)
         {
             GenericType* pNew = pVar->getColumnValues(i);
+
+            if (pNew == NULL)
+            {
+                pIT->DecreaseRef();
+                pIT->killMe();
+                throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
+            }
+
             symbol::Context::getInstance()->put(e.getVardec().getStack(), pNew);
 
             e.getBody().accept(*this);
@@ -443,6 +453,12 @@ void RunVisitorT<T>::visitprivate(const ForExp  &e)
             }
         }
     }
+    else
+    {
+        pIT->DecreaseRef();
+        pIT->killMe();
+        throw ScilabError(_W("for expression : Wrong type for loop iterator.\n"), 999, e.getVardec().getLocation());
+    }
 
     pIT->DecreaseRef();
     pIT->killMe();
index e8b53ed..ba43ec3 100644 (file)
@@ -23,6 +23,7 @@
 #include "serializervisitor.hxx"
 #include "deserializervisitor.hxx"
 #include "localization.hxx"
+#include "user.hxx"
 
 #include "alltypes.hxx"
 
@@ -686,7 +687,10 @@ bool getFieldsFromExp(ast::Exp* _pExp, std::list<ExpHistory*>& fields)
         typed_list* pCurrentArgs = execMe.GetArgumentList(pCall->getArgs());
 
         bool bErr = getFieldsFromExp(&pCall->getName(), fields);
-        if (pCurrentArgs && (*pCurrentArgs)[0]->isString())
+        if (pCurrentArgs                    &&
+                pCurrentArgs->size() == 1       &&
+                (*pCurrentArgs)[0]->isString()  &&
+                (*pCurrentArgs)[0]->getAs<String>()->getSize() == 1)
         {
             // a("b") => a.b or a(x)("b") => a(x).b
             ExpHistory * pEHParent = fields.back();
@@ -858,7 +862,7 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
         {
             TList* pTL = pITCurrent->getAs<TList>();
             typed_list* pArgs = pEH->getArgs();
-            if (pArgs && (*pArgs)[0]->isString() == false)
+            if (pArgs)
             {
                 if (pArgs->size() > 1 || pITCurrent->isMList())
                 {
@@ -866,15 +870,15 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                     InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
                     if ((*iterFields)->getExp() == NULL)
                     {
-                        // a(x)(y) => a.b(y)
-                        // extract a(x) and push_BACK to extract next level
+                        // a(x)(y)
+                        // extract a(x) and push_BACK to extract y
                         workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
                         workFields.back()->setReinsertion();
                     }
                     else
                     {
                         // a(x).b
-                        // extract a(x) and push_FRONT to extract b from a(x)
+                        // extract a(x) and push_FRONT to extract b
                         workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
                         workFields.front()->setReinsertion();
                     }
@@ -888,30 +892,32 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                         pTL->set(iNewSize - 1, new ListUndefined());
                     }
 
-                    std::vector<InternalType*> vectpIT = pTL->extract(pArgs);
-                    std::vector<InternalType*>::iterator iterVect;
+                    // update pArgs variables with new argument computed in getSizeFromArgs
+                    pArgs = pEH->getArgs();
+
+                    InternalType* pIT = pTL->extract(pArgs);
+                    List* pList = pIT->getAs<List>();
                     double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
-                    int iLoop = 0;
 
                     if ((*iterFields)->getExp() == NULL)
                     {
-                        // a(x)(y) => a.b(y)
-                        // extract a(x) and push_BACK to extract next level
-                        for (iterVect = vectpIT.begin(); iterVect != vectpIT.end(); iterVect++, iLoop++)
+                        // a(x)(y)
+                        // extract a(x) and push_BACK to extract y
+                        for (int i = 0; i < pList->getSize(); i++)
                         {
-                            ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), *iterVect);
-                            pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
+                            ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(i));
+                            pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
                             workFields.push_back(pEHExtract);
                         }
                     }
                     else
                     {
                         // a(x).b
-                        // extract a(x) and push_FRONT to extract b from a(x)
-                        for (iterVect = vectpIT.begin(); iterVect != vectpIT.end(); iterVect++, iLoop++)
+                        // extract a(x) and push_FRONT to extract b
+                        for (int i = 0; i < pList->getSize(); i++)
                         {
-                            ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), *iterVect);
-                            pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
+                            ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(i));
+                            pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
                             workFields.push_front(pEHExtract);
                         }
                     }
@@ -919,22 +925,13 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
             }
             else
             {
-                // get string "x"
+                // get string "x" of a.x
                 InternalType* pExtract = NULL;
                 std::wstring pwcsFieldname = L"";
                 bool bReinsert = false;
                 ExpHistory* pEHChield = NULL;
 
-                if (pArgs)
-                {
-                    // a('x')
-                    pwcsFieldname = (*pArgs)[0]->getAs<String>()->get(0);
-                }
-                else
-                {
-                    // a.x
-                    pwcsFieldname = (*iterFields)->getExpAsString();
-                }
+                pwcsFieldname = (*iterFields)->getExpAsString();
 
                 // check if field exists
                 if (pTL->exists(pwcsFieldname) == false)
@@ -946,20 +943,14 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                     {
                         // M=mlist(['MType','x','y'], ...
                         // M.rows1 = "somthing"
-                        if (pArgs == NULL)
-                        {
-                            pArgs = new typed_list();
-                            pArgs->push_back(new String(pwcsFieldname.c_str()));
-                        }
+                        pArgs = new typed_list();
+                        pArgs->push_back(new String(pwcsFieldname.c_str()));
 
                         // call overload
                         pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
                         bReinsert = true;
 
-                        if (pEH->getArgs() == NULL)
-                        {
-                            delete pArgs;
-                        }
+                        delete pArgs;
                     }
                 }
                 else
@@ -968,30 +959,8 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                     pExtract = pTL->getField(pwcsFieldname);
                 }
 
-                // History management
-                if (pEH->getArgs())
-                {
-                    if ((*iterFields)->getExp() == NULL)
-                    {
-                        // a('x')(y) => a.b(y)
-                        // extract a(x) and push_BACK to extract next level
-                        pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
-                        workFields.push_back(pEHChield);
-                    }
-                    else
-                    {
-                        // a('x').b -> a('x')('b')
-                        // extract a(x) and push_FRONT to extract b from a(x)
-                        pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract);
-                        workFields.push_front(pEHChield);
-                    }
-                }
-                else
-                {
-                    // a.x
-                    pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
-                    workFields.push_back(pEHChield);
-                }
+                pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
+                workFields.push_back(pEHChield);
 
                 if (bReinsert)
                 {
@@ -1220,59 +1189,65 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
             }
         }
-        else if (pITCurrent == 0) // implicit struct creation
-        {
-            InternalType* pIT = new Struct(1, 1);
-            pEH->setCurrent(pIT);
-            pEH->setReinsertion();
-
-            workFields.push_front(pEH);
-            evalFields.pop_back();
-        }
-        else // not a Scilab defined datatype, access field after field
+        else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
         {
-            typed_list* pArgs = pEH->getArgs();
-
-            // get string "x"
-            std::wstring pwcsFieldname = L"";
-            ExpHistory* pEHChield = 0;
-
-            if (pArgs)
-            {
-                // a('x')
-                pwcsFieldname = (*pArgs)[0]->getAs<String>()->get(0);
-            }
-            else
+            // call userType extract method
+            if (pEH->getArgs())
             {
-                // a.x
-                pwcsFieldname = (*iterFields)->getExpAsString();
-            }
+                // a(x)
+                InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(pEH->getArgs());
+                if (pExtract == NULL)
+                {
+                    // call overload
+                    pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
+                }
 
-            // History management
-            if (pArgs)
-            {
                 if ((*iterFields)->getExp() == NULL)
                 {
-                    // a('x')(y) => a.b(y)
+                    // a(x)(y)
                     // extract a(x) and push_BACK to extract next level
-                    pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), 0);
-                    workFields.push_back(pEHChield);
+                    workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
+                    workFields.back()->setReinsertion();
                 }
                 else
                 {
-                    // a('x').b -> a('x')('b')
+                    // a(x).b
                     // extract a(x) and push_FRONT to extract b from a(x)
-                    pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), 0);
-                    workFields.push_front(pEHChield);
+                    workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
+                    workFields.front()->setReinsertion();
                 }
             }
             else
             {
-                // a.x
-                pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), 0);
-                workFields.push_back(pEHChield);
+                // a.x, get string "x"
+                std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+
+                // create arg with next field
+                typed_list* args = new typed_list();
+                args->push_back(new String(pwcsFieldname.c_str()));
+                pEH->setArgs(args);
+
+                InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(args);
+                if (pExtract == NULL)
+                {
+                    // call overload
+                    pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
+                }
+
+                // append extraction of a.x for next level.
+                workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
+                workFields.front()->setReinsertion();
             }
         }
+        else
+        {
+            InternalType* pIT = new Struct(1, 1);
+            pEH->setCurrent(pIT);
+            pEH->setReinsertion();
+
+            workFields.push_front(pEH);
+            evalFields.pop_back();
+        }
 
         if (workFields.front()->getLevel() == (*iterFields)->getLevel())
         {
@@ -1433,11 +1408,6 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                         continue;
                     }
                 }
-                else
-                {
-                    pParentArgs = new typed_list();
-                    pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
-                }
             }
 
             InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
@@ -2076,6 +2046,14 @@ InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType*
                 pRet = _pVar->getAs<types::GraphicHandle>()->extract(_pArgs);
             }
         }
+        else if (_pVar->isUserType())
+        {
+            pRet = _pVar->getAs<types::UserType>()->insert(_pArgs, _pInsert);
+            if (pRet == NULL)
+            {
+                pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
+            }
+        }
         else
         {
             // overload
index 21a3315..ab0655e 100644 (file)
@@ -111,11 +111,6 @@ InternalType *List::clone()
     return new List(this);
 }
 
-GenericType* List::getColumnValues(int /*_iPos*/)
-{
-    return NULL;
-}
-
 /**
 ** toString to display Lists
 ** FIXME : Find a better indentation process
@@ -146,9 +141,9 @@ bool List::toString(std::wostringstream& ostr)
     return true;
 }
 
-std::vector<InternalType*>     List::extract(typed_list* _pArgs)
+InternalType* List::extract(typed_list* _pArgs)
 {
-    std::vector<InternalType*> outList;
+    List* outList = new List();
     //check input param
     if (_pArgs->size() != 1)
     {
@@ -173,11 +168,12 @@ std::vector<InternalType*>        List::extract(typed_list* _pArgs)
         int idx = (int)pArg[0]->getAs<Double>()->get(i);
         if (idx > getSize() || idx < 1)
         {
-            outList.clear();
+            delete outList;
+            outList = new List();
             break;
         }
         InternalType* pIT = (*m_plData)[idx - 1];
-        outList.push_back(pIT);
+        outList->set(i, pIT);
     }
 
     //free pArg content
@@ -328,23 +324,32 @@ bool List::set(const int _iIndex, InternalType* _pIT)
         return false;
     }
 
-    while ((int)m_plData->size() <= _iIndex)
+    while ((int)m_plData->size() < _iIndex)
     {
         //incease list size and fill with "Undefined"
         m_plData->push_back(new ListUndefined());
         m_iSize = getSize();
     }
 
-    InternalType* pOld = (*m_plData)[_iIndex];
+    if ((int)m_plData->size() == _iIndex)
+    {
+        _pIT->IncreaseRef();
+        m_plData->push_back(_pIT);
+        m_iSize = getSize();
+    }
+    else
+    {
+        InternalType* pOld = (*m_plData)[_iIndex];
 
-    _pIT->IncreaseRef();
-    (*m_plData)[_iIndex] = _pIT;
+        _pIT->IncreaseRef();
+        (*m_plData)[_iIndex] = _pIT;
 
-    //manage ref on the old value
-    if (pOld)
-    {
-        pOld->DecreaseRef();
-        pOld->killMe();
+        //manage ref on the old value
+        if (pOld)
+        {
+            pOld->DecreaseRef();
+            pOld->killMe();
+        }
     }
 
     return true;
index ddd2510..0e6df6b 100644 (file)
@@ -31,7 +31,7 @@ bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/,
     else if (in.size() == 1)
     {
         InternalType * arg = in[0];
-        std::vector<InternalType *> _out;
+        InternalType* _out = NULL;
         if (arg->isString())
         {
             std::list<std::wstring> stFields;
@@ -42,11 +42,18 @@ bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/,
             }
 
             _out = extractStrings(stFields);
+
+            List* pList = _out->getAs<types::List>();
+            for (int i = 0; i < pList->getSize(); i++)
+            {
+                out.push_back(pList->get(i));
+            }
+
+            delete pList;
         }
 
-        if (!_out.empty())
+        if (!out.empty())
         {
-            out.swap(_out);
             return true;
         }
     }
index a66f584..bb69989 100644 (file)
@@ -540,14 +540,14 @@ InternalType * Struct::extractField(const std::wstring & wstField)
     {
         if (getSize() == 1)
         {
-            return get(0)->get(wstField)->clone();
+            return get(0)->get(wstField);
         }
         else
         {
             List * pL = new List();
             for (int j = 0 ; j < getSize() ; j++)
             {
-                pL->append(get(j)->get(wstField)->clone());
+                pL->append(get(j)->get(wstField));
             }
 
             return pL;
index 68ecb72..f979a02 100644 (file)
@@ -86,10 +86,18 @@ bool TList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/,
     else if (in.size() == 1)
     {
         InternalType * arg = in[0];
-        std::vector<InternalType *> _out;
+        InternalType * _out = NULL;
         if (arg->isDouble() || arg->isInt() || arg->isBool() || arg->isImplicitList() || arg->isColon() || arg->isDollar())
         {
             _out = List::extract(&in);
+
+            List* pList = _out->getAs<types::List>();
+            for (int i = 0; i < pList->getSize(); i++)
+            {
+                out.push_back(pList->get(i));
+            }
+
+            delete pList;
         }
         else if (arg->isString())
         {
@@ -101,11 +109,18 @@ bool TList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/,
             }
 
             _out = extractStrings(stFields);
+
+            List* pList = _out->getAs<types::List>();
+            for (int i = 0; i < pList->getSize(); i++)
+            {
+                out.push_back(pList->get(i));
+            }
+
+            delete pList;
         }
 
-        if (!_out.empty())
+        if (!out.empty())
         {
-            out.swap(_out);
             return true;
         }
     }
@@ -172,23 +187,25 @@ int TList::getIndexFromString(const std::wstring& _sKey)
     return -1;
 }
 
-std::vector<InternalType*> TList::extractStrings(const std::list<std::wstring>& _stFields)
+InternalType* TList::extractStrings(const std::list<std::wstring>& _stFields)
 {
-    std::vector<InternalType*> Result;
+    int i = 0;
+    List* pLResult = new List();
     std::list<std::wstring>::const_iterator it;
     for (it = _stFields.begin() ; it != _stFields.end() ; it++)
     {
         if (exists(*it) == false)
         {
-            return Result;
+            return pLResult;
         }
     }
 
-    for (it = _stFields.begin() ; it != _stFields.end() ; it++)
+    for (it = _stFields.begin() ; it != _stFields.end() ; it++, i++)
     {
-        Result.push_back(getField(*it));
+        pLResult->set(i, getField(*it));
     }
-    return Result;
+
+    return pLResult;
 }
 
 std::wstring TList::getTypeStr()
index 178946e..8e0d7df 100644 (file)
@@ -85,17 +85,18 @@ int checkIndexesArguments(InternalType* _pRef, typed_list* _pArgsIn, typed_list*
         else if (pIT->isString())
         {
             String* pStr = pIT->getAs<String>();
-            if (_pArgsIn->size() != 1 || pStr->isScalar() == false)
-            {
-                bUndefine = true;
-                continue;
-            }
-
-            wchar_t* pFieldName = pStr->get(0);
-
             if (_pRef->isStruct())
             {
                 Struct* pStruct = _pRef->getAs<Struct>();
+
+                if (_pArgsIn->size() != 1 || pStr->isScalar() == false)
+                {
+                    bUndefine = true;
+                    continue;
+                }
+
+                wchar_t* pFieldName = pStr->get(0);
+
                 // pCurrent arg is indexed to 1 unlike the return of "getFieldIndex"
                 int iIndex = pStruct->get(0)->getFieldIndex(pFieldName) + 1;
                 if (iIndex == -1)
@@ -106,19 +107,32 @@ int checkIndexesArguments(InternalType* _pRef, typed_list* _pArgsIn, typed_list*
 
                 pCurrentArg = new Double((double)iIndex);
             }
-            else if (_pRef->isList())
+            else if (_pRef->isTList())
             {
+                // List cant be extract by field and MList must call overload
+                TList* pTL = _pRef->getAs<TList>();
+                pCurrentArg = new Double(pStr->getDims(), pStr->getDimsArray());
+                double* pdbl = pCurrentArg->get();
+                for (int i = 0; i < pStr->getSize(); i++)
+                {
+                    wchar_t* pFieldName = pStr->get(i);
+                    int iIndex = pTL->getIndexFromString(pFieldName);
+                    if (iIndex == -1)
+                    {
+                        bUndefine = true;
+                        continue;
+                    }
+                    pdbl[i] = (double)(iIndex + 1);
+                }
             }
             else if (_pRef->isCell())
             {
             }
             else
             {
+                bUndefine = true;
+                break;
             }
-
-            //_pArgsOut->push_back(NULL);
-            bUndefine = true;
-            break;
         }
         else if (pIT->isPoly())
         {
index c709461..ea67e61 100644 (file)
@@ -45,15 +45,16 @@ types::Function::ReturnValue sci_getfield(types::typed_list &in, int _iRetCount,
     }
 
     types::InternalType* pIndex = in[0];
-    types::List* pL = in[1]->getAs<types::List>();
-    std::vector<types::InternalType*> vOut;
-
-    if (pL->isList() == false && pL->isMList() == false && pL->isTList() == false)
+    if (in[1]->isList() == false && in[1]->isMList() == false && in[1]->isTList() == false)
     {
         Scierror(999, _("%s:  Wrong type for input argument #%d: List expected.\n"), "getfield", 2);
         return types::Function::Error;
     }
 
+    types::List* pL = in[1]->getAs<types::List>();
+    types::InternalType* pITOut = NULL;
+
+
     if (pIndex->isString())
     {
         //extraction by fieldnames
@@ -81,26 +82,28 @@ types::Function::ReturnValue sci_getfield(types::typed_list &in, int _iRetCount,
             stFields.push_back(pS->get(i));
         }
 
-        vOut = pT->extractStrings(stFields);
+        pITOut = pT->extractStrings(stFields);
     }
     else
     {
         //extraction by index
         types::typed_list Args;
         Args.push_back(pIndex);
-        vOut = pL->extract(&Args);
+        pITOut = pL->extract(&Args);
     }
 
+    types::List* pList = pITOut->getAs<types::List>();
+    int iListSize = pList->getSize();
 
-    if (_iRetCount < vOut.size())
+    if (_iRetCount < iListSize)
     {
-        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "getfield", vOut.size());
+        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "getfield", iListSize);
         return types::Function::Error;
     }
 
-    for (int i = 0 ; i < vOut.size() ; i++)
+    for (int i = 0 ; i < iListSize ; i++)
     {
-        out.push_back(vOut[i]);
+        out.push_back(pList->get(i));
     }
 
     return types::Function::OK;
index b427ab7..3f64f94 100644 (file)
@@ -95,7 +95,7 @@ public:
  * Note that sub-classes are responsible to fill the fields accordingly to theirs interfaces.
  */
 template<typename Adaptor, typename Adaptee>
-class BaseAdapter : public types::User<Adaptor>
+class BaseAdapter : public types::UserType
 {
 
 public:
@@ -233,18 +233,25 @@ public:
      * All following methods should be implemented by each template instance
      */
 
-    virtual std::wstring getTypeStr() = 0;
-    virtual std::wstring getShortTypeStr() = 0;
+    std::wstring getTypeStr()
+    {
+        return L"ba";
+    }
+
+    std::wstring getShortTypeStr()
+    {
+        return L"BaseAdapter";
+    }
 
-    /*
-     * Implement a specific types::User
-     */
-private:
     types::InternalType* clone()
     {
         return new Adaptor(*static_cast<Adaptor*>(this));
     }
 
+    /*
+     * Implement a specific types::User
+     */
+
     bool isAssignable()
     {
         return true;
@@ -268,11 +275,71 @@ private:
         return false;
     }
 
+    types::InternalType* extract(types::typed_list* _pArgs)
+    {
+        if (_pArgs->size() == 0)
+        {
+            // call overload
+            return NULL;
+        }
+
+        if ((*_pArgs)[0]->isString())
+        {
+            types::String* pStr = (*_pArgs)[0]->getAs<types::String>();
+            types::InternalType* pOut = NULL;
+            extract(std::wstring(pStr->get(0)), pOut);
+            return pOut;
+        }
+        else
+        {
+            // TO DO : management other type for arguments like a scalar or matrix of double
+        }
+
+        return NULL;
+    }
+
+    types::InternalType* insert(types::typed_list* _pArgs, InternalType* _pSource)
+    {
+        for (int i = 0; i < _pArgs->size(); i++)
+        {
+            if ((*_pArgs)[i]->isString())
+            {
+                types::String* pStr = (*_pArgs)[i]->getAs<types::String>();
+                std::wstring name = pStr->get(0);
+                Controller controller = Controller();
+                typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), name);
+                if (found != property<Adaptor>::fields.end() && !(name < found->name))
+                {
+                    found->set(*static_cast<Adaptor*>(this), _pSource, controller);
+                }
+
+                return this;
+            }
+            //else if(_pArgs[i]->isDouble())
+            //{
+            //
+            //}
+            else
+            {
+                return NULL;
+            }
+        }
+
+        // call overload
+        return NULL;
+    }
+
     void whoAmI(void)
     {
         std::cout << "scicos object";
     }
 
+    bool hasToString()
+    {
+        // allow scilab to call toString of this class
+        return true;
+    }
+
     bool toString(std::wostringstream& ostr)
     {
         typename property<Adaptor>::props_t properties = property<Adaptor>::fields;
index 2c5ba90..758f8fa 100644 (file)
@@ -71,11 +71,11 @@ struct gui
 {
     static types::InternalType* get(const BlockAdapter& adaptor, const Controller& controller)
     {
-        std::string interface;
+        std::string Interface;
         org_scilab_modules_scicos::model::Block* adaptee = adaptor.getAdaptee();
-        controller.getObjectProperty(adaptee->id(), adaptee->kind(), INTERFACE_FUNCTION, interface);
+        controller.getObjectProperty(adaptee->id(), adaptee->kind(), INTERFACE_FUNCTION, Interface);
 
-        return new types::String(interface.data());
+        return new types::String(Interface.data());
     }
 
     static bool set(BlockAdapter& adaptor, types::InternalType* v, Controller& controller)
index 7775cc6..e4efc7a 100644 (file)
@@ -24,7 +24,7 @@ extern "C" {
 
 using namespace types;
 
-class MyDataType : public User<MyDataType>
+class MyDataType : public UserType
 {
 public:
     MyDataType(std::wstring _shortName, std::wstring _longName) :