insertion implicitList in callExp/cellExp fixed. 25/15425/7
Cedric Delamarre [Mon, 27 Oct 2014 09:13:21 +0000 (10:13 +0100)]
test_run elementary_functions find

A=[];A(2,3,2) = 0;A(:)=1:12;

ml = mlist(["toto", "f1"], 14);
a.b = ml;
a.b(2) = 12; // leek after overload error

c{:} = 1:12

st.b(2).c = ml;
st.b(2).c(2) = 12; // leek after overload error

Change-Id: I61992aa9300301a7d544963382867021b896ee39

scilab/modules/ast/includes/ast/expHistory.hxx
scilab/modules/ast/src/cpp/ast/expHistory.cpp
scilab/modules/ast/src/cpp/ast/run_AssignExp.cpp
scilab/modules/ast/src/cpp/ast/visitor_common.cpp
scilab/modules/ast/src/cpp/types/cell.cpp

index cec4ada..26e9f19 100644 (file)
@@ -48,6 +48,7 @@ public :
     // current InternalType a
     bool                    setCurrent(types::InternalType*);
     types::InternalType*    getCurrent();
+    void                    setDeleteCurrent(bool bDelete); // false by default
 
     // parent of me
     ExpHistory*             getParent();
@@ -83,6 +84,8 @@ private :
     int                     m_iLevel;
     bool                    m_pArgsOwner;
     bool                    m_pExpOwner;
+    bool                    m_bDeleteCurrent;
+
 };
 
 #endif /* __EXPHISTORY_HXX__ */
index 1cae032..9ce0e82 100644 (file)
 ** Constructor & Destructor (public)
 */
 
-ExpHistory::ExpHistory() : m_pArgs(NULL), m_piArgsDimsArray(NULL), m_pExp(NULL), m_pParent(NULL), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false)
+ExpHistory::ExpHistory() : m_pArgs(NULL), m_piArgsDimsArray(NULL), m_pExp(NULL), m_pParent(NULL), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false), m_bDeleteCurrent(false)
 {
 }
 
 
-ExpHistory::ExpHistory(ExpHistory* _pEH, ast::SimpleVar* _pExp) : m_pArgs(NULL), m_piArgsDimsArray(NULL), m_pExp(_pExp), m_pParent(_pEH), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false)
+ExpHistory::ExpHistory(ExpHistory* _pEH, ast::SimpleVar* _pExp) : m_pArgs(NULL), m_piArgsDimsArray(NULL), m_pExp(_pExp), m_pParent(_pEH), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false), m_bDeleteCurrent(false)
 {
 }
 
-ExpHistory::ExpHistory(ExpHistory* _pParent, types::typed_list* _pArgs) : m_pArgs(_pArgs), m_piArgsDimsArray(NULL), m_pExp(NULL), m_pParent(_pParent), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false)
+ExpHistory::ExpHistory(ExpHistory* _pParent, types::typed_list* _pArgs) : m_pArgs(_pArgs), m_piArgsDimsArray(NULL), m_pExp(NULL), m_pParent(_pParent), m_pITCurrent(NULL), m_bReinsertMe(false), m_bCellExp(false), m_iArgsDims(0), m_iWhere(-1), m_iLevel(0), m_pArgsOwner(false), m_pExpOwner(false), m_bDeleteCurrent(false)
 {
 }
 
@@ -44,7 +44,8 @@ ExpHistory::ExpHistory(ExpHistory* _pParent, ast::SimpleVar* _pExp, types::typed
     m_iWhere(-1),
     m_iLevel(_iLevel),
     m_pArgsOwner(false),
-    m_pExpOwner(false)
+    m_pExpOwner(false),
+    m_bDeleteCurrent(false)
 {
 }
 
@@ -71,6 +72,11 @@ ExpHistory::~ExpHistory()
         delete m_pArgs;
         m_pArgs = NULL;
     }
+
+    if (m_pITCurrent && m_bDeleteCurrent)
+    {
+        m_pITCurrent->killMe();
+    }
 }
 
 /**
@@ -118,6 +124,11 @@ void ExpHistory::setExpOwner(bool owner)
     m_pExpOwner = owner;
 }
 
+void ExpHistory::setDeleteCurrent(bool bDelete)
+{
+    m_bDeleteCurrent = bDelete;
+}
+
 void ExpHistory::computeArgs()
 {
     if (m_pArgs)
index fcbb09f..81204fa 100644 (file)
@@ -129,12 +129,30 @@ void RunVisitorT<T>::visitprivate(const AssignExp  &e)
                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
             }
 
-            pOut = evaluateFields(pCell, fields, pITR);
+            try
+            {
+                pOut = evaluateFields(pCell, fields, pITR);
+            }
+            catch (ast::ScilabError error)
+            {
+                // catch error when call overload
+                for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
+                {
+                    (*i)->setDeleteCurrent(true);
+                    delete *i;
+                }
+
+                pITR->killMe();
+                throw error;
+            }
+
             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
             {
                 delete *i;
             }
 
+            pITR->killMe();
+
             if (pOut == NULL)
             {
                 std::wostringstream os;
@@ -147,9 +165,10 @@ void RunVisitorT<T>::visitprivate(const AssignExp  &e)
                 if (e.isVerbose() && ConfigVariable::isPromptShow())
                 {
                     std::wostringstream ostr;
-                    if (pVar)
+                    if (pCell)
                     {
-                        ostr << SPACES_LIST << pVar->getSymbol().getName();
+                        const wstring *pstName = getStructNameFromExp(pCell);
+                        ostr << SPACES_LIST << pstName;
                     }
                     else
                     {
@@ -174,7 +193,7 @@ void RunVisitorT<T>::visitprivate(const AssignExp  &e)
         if (pCall)
         {
             //x(?) = ?
-            InternalType *pOut = NULL;
+            InternalType *pOut = NULL;
 
             /*getting what to assign*/
             InternalType* pITR = e.getRightVal();
@@ -206,12 +225,36 @@ void RunVisitorT<T>::visitprivate(const AssignExp  &e)
                 throw ast::ScilabError(os.str(), 999, e.getRightExp().getLocation());
             }
 
-            pOut = evaluateFields(pCall, fields, pITR);
+            // prevent delete after extractFullMatrix
+            // called in evaluateFields when pITR is an ImplicitList
+            pITR->IncreaseRef();
+
+            try
+            {
+                pOut = evaluateFields(pCall, fields, pITR);
+            }
+            catch (ast::ScilabError error)
+            {
+                // catch error when call overload
+                for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
+                {
+                    delete *i;
+                }
+
+                pITR->DecreaseRef();
+                pITR->killMe();
+
+                throw error;
+            }
+
             for (std::list<ExpHistory*>::const_iterator i = fields.begin(), end = fields.end(); i != end; i++)
             {
                 delete *i;
             }
 
+            pITR->DecreaseRef();
+            pITR->killMe();
+
             if (pOut == NULL)
             {
                 std::wostringstream os;
@@ -231,8 +274,6 @@ void RunVisitorT<T>::visitprivate(const AssignExp  &e)
                 VariableToString(pOut, ostrName.str().c_str());
             }
 
-            pITR->killMe();
-
             clearResult();
             return;
         }
index 8cf877a..eced9ef 100644 (file)
@@ -575,6 +575,7 @@ const std::wstring* getStructNameFromExp(const ast::Exp* _pExp)
 //source : data to insert               || extract indexes from source
 types::InternalType* callOverload(const ast::Exp& e, std::wstring _strType, types::typed_list* _pArgs, types::InternalType* _source, types::InternalType* _dest)
 {
+    types::Function::ReturnValue ret = types::Function::Error;
     types::InternalType* pITOut = NULL;
     types::typed_list in;
     types::typed_list out;
@@ -609,9 +610,41 @@ types::InternalType* callOverload(const ast::Exp& e, std::wstring _strType, type
     // For insertion in TList, call normal insertion if overload doesn't exits
     if ((_dest  && _dest->isTList() && pFunc == NULL) == false || _source->isListDelete())
     {
+        bool bThrow = false;
+        ast::ScilabError se;
         ast::ExecVisitor exec;
-        if (Overload::call(function_name, in, 1, out, &exec))
+
+        try
+        {
+            ret = Overload::call(function_name, in, 1, out, &exec);
+        }
+        catch (ast::ScilabError error)
         {
+            bThrow = true;
+            se = error;
+        }
+
+        if (ret == types::Function::Error)
+        {
+            for (int i = 0; i < (int)_pArgs->size(); i++)
+            {
+                (*_pArgs)[i]->DecreaseRef();
+                (*_pArgs)[i]->killMe();
+            }
+
+            _source->DecreaseRef();
+            _source->killMe();
+            if (_dest)
+            {
+                _dest->DecreaseRef();
+                _dest->killMe();
+            }
+
+            if (bThrow)
+            {
+                throw se;
+            }
+
             //manage error
             std::wostringstream os;
             os << _W("Error in overload function: ") << function_name << std::endl;
@@ -737,306 +770,189 @@ bool getFieldsFromExp(ast::Exp* _pExp, std::list<ExpHistory*>& fields)
 types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fields, InternalType* _pAssignValue)
 {
     std::list<ExpHistory*> evalFields;
+    std::list<ExpHistory*> workFields;
 
-    //*** get main variable ***//
-    std::list<ExpHistory*>::iterator iterFields = fields.begin();
-    ExpHistory* pFirstField = *iterFields;
-    InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
-    if (pIT == NULL)
+    try
     {
-        if (pFirstField->isCellExp())
+        //*** get main variable ***//
+        std::list<ExpHistory*>::iterator iterFields = fields.begin();
+        ExpHistory* pFirstField = *iterFields;
+        InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
+        if (pIT == NULL)
         {
-            // a{x}, where "a" doesn't exists
-            pIT = new Cell(1, 1);
-            symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
+            if (pFirstField->isCellExp())
+            {
+                // a{x}, where "a" doesn't exists
+                pIT = new Cell(1, 1);
+                symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
+            }
+            else if (fields.size() > 1)
+            {
+                // is a field exp
+                //"a" does not exist or it is another type, create it with size 1,1 and return it
+                //create new structure variable
+                pIT = new Struct(1, 1);
+                symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
+            }
+            // else
+            // is a call exp
+            // a(x) = "something" and a does not exist
+            // a will be create in insertionCall
         }
-        else if (fields.size() > 1)
+        else if (pIT->getRef() > 1 && pIT->isHandle() == false)
         {
-            // is a field exp
-            //"a" does not exist or it is another type, create it with size 1,1 and return it
-            //create new structure variable
-            pIT = new Struct(1, 1);
+            pIT = pIT->clone();
             symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
         }
-        // else
-        // is a call exp
-        // a(x) = "something" and a does not exist
-        // a will be create in insertionCall
-    }
-    else if (pIT->getRef() > 1 && pIT->isHandle() == false)
-    {
-        pIT = pIT->clone();
-        symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
-    }
-    else if (pIT == _pAssignValue)
-    {
-        // clone me before insert me in myself.
-        // ie : a.b = 2; a.b.c.d = a;
-        _pAssignValue = _pAssignValue->clone();
-    }
-
-    iterFields++;
+        else if (pIT == _pAssignValue)
+        {
+            // clone me before insert me in myself.
+            // ie : a.b = 2; a.b.c.d = a;
+            _pAssignValue = _pAssignValue->clone();
+        }
 
-    std::list<ExpHistory*> workFields;
-    workFields.push_back(new ExpHistory(NULL,
-                                        pFirstField->getExp(),
-                                        pFirstField->getArgs(),
-                                        pFirstField->getLevel(),
-                                        pFirstField->isCellExp(),
-                                        pIT));
-
-    //*** evaluate fields ***//
-    while (iterFields != fields.end())
-    {
-        ExpHistory* pEH = workFields.front();
-        evalFields.push_back(pEH);
-        workFields.pop_front();
+        iterFields++;
 
-        types::InternalType* pITCurrent = pEH->getCurrent();
+        workFields.push_back(new ExpHistory(NULL,
+                                            pFirstField->getExp(),
+                                            pFirstField->getArgs(),
+                                            pFirstField->getLevel(),
+                                            pFirstField->isCellExp(),
+                                            pIT));
 
-        if (pEH->isCellExp() && pITCurrent->isCell() == false)
+        //*** evaluate fields ***//
+        while (iterFields != fields.end())
         {
-            std::wostringstream os;
-            os << _W("Wrong insertion : use extraction with {} only on a Cell.");
-            throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
-        }
+            ExpHistory* pEH = workFields.front();
+            evalFields.push_back(pEH);
+            workFields.pop_front();
 
-        if (pITCurrent->isStruct())
-        {
-            Struct* pStruct = pITCurrent->getAs<Struct>();
-            std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+            types::InternalType* pITCurrent = pEH->getCurrent();
 
-            if (pEH->needResize())
+            if (pEH->isCellExp() && pITCurrent->isCell() == false)
             {
-                if (pEH->getArgsDims() == 1)
-                {
-                    std::wostringstream os;
-                    os << _W("Invalid index.");
-                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
-                }
-
-                // resize current struct
-                pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
+                std::wostringstream os;
+                os << _W("Wrong insertion : use extraction with {} only on a Cell.");
+                throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
             }
 
-            // create field in parent if it not exist
-            if (pStruct->exists(pwcsFieldname) == false)
+            if (pITCurrent->isStruct())
             {
-                pStruct->addField(pwcsFieldname);
-            }
+                Struct* pStruct = pITCurrent->getAs<Struct>();
+                std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
 
-            if (pEH->getArgs())
-            {
-                InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
-                workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
-            }
-            else
-            {
-                // extract field x and append it to elements for next recursion.
-                List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
-                for (int iList = 0; iList < pLOut->getSize(); iList++)
+                if (pEH->needResize())
                 {
-                    InternalType* pIT = pLOut->get(iList);
-                    if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
+                    if (pEH->getArgsDims() == 1)
                     {
-                        // clone element before modify it.
-                        //pIT->DecreaseRef();
-                        pIT = pIT->clone();
-                        pStruct->get(iList)->set(pwcsFieldname, pIT);
+                        std::wostringstream os;
+                        os << _W("Invalid index.");
+                        throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
                     }
 
-                    ExpHistory* pEHChield = new ExpHistory( pEH,
-                                                            (*iterFields)->getExp(),
-                                                            (*iterFields)->getArgs(),
-                                                            (*iterFields)->getLevel(),
-                                                            (*iterFields)->isCellExp(),
-                                                            pIT);
-                    pEHChield->setWhereReinsert(iList);
-                    workFields.push_back(pEHChield);
+                    // resize current struct
+                    pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
                 }
 
-                pLOut->killMe();
-            }
-        }
-        else if (pITCurrent->isTList() || pITCurrent->isMList())
-        {
-            TList* pTL = pITCurrent->getAs<TList>();
-            typed_list* pArgs = pEH->getArgs();
-            if (pArgs)
-            {
-                if (pArgs->size() > 1 || pITCurrent->isMList())
+                // create field in parent if it not exist
+                if (pStruct->exists(pwcsFieldname) == false)
                 {
-                    // call overload
-                    InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
-                    if ((*iterFields)->getExp() == NULL)
-                    {
-                        // 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
-                        workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
-                        workFields.front()->setReinsertion();
-                    }
+                    pStruct->addField(pwcsFieldname);
                 }
-                else
-                {
-                    // resize TList
-                    int iNewSize = pEH->getSizeFromArgs();
-                    if (pTL->getSize() < iNewSize)
-                    {
-                        pTL->set(iNewSize - 1, new ListUndefined());
-                    }
-
-                    // 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();
 
-                    if ((*iterFields)->getExp() == NULL)
-                    {
-                        // 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(), 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
-                        for (int i = 0; i < pList->getSize(); i++)
-                        {
-                            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);
-                        }
-                    }
-                }
-            }
-            else
-            {
-                // get string "x" of a.x
-                InternalType* pExtract = NULL;
-                std::wstring pwcsFieldname = L"";
-                bool bReinsert = false;
-                ExpHistory* pEHChield = NULL;
-
-                pwcsFieldname = (*iterFields)->getExpAsString();
-
-                // check if field exists
-                if (pTL->exists(pwcsFieldname) == false)
+                if (pEH->getArgs())
                 {
-                    std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
-                    ++iterFieldsNext;
-
-                    if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
-                    {
-                        // M=mlist(['MType','x','y'], ...
-                        // M.rows1 = "somthing"
-                        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;
-
-                        delete pArgs;
-                    }
+                    InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
+                    workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
                 }
                 else
                 {
                     // extract field x and append it to elements for next recursion.
-                    pExtract = pTL->getField(pwcsFieldname);
-                }
+                    List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
+                    for (int iList = 0; iList < pLOut->getSize(); iList++)
+                    {
+                        InternalType* pIT = pLOut->get(iList);
+                        if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
+                        {
+                            // clone element before modify it.
+                            //pIT->DecreaseRef();
+                            pIT = pIT->clone();
+                            pStruct->get(iList)->set(pwcsFieldname, pIT);
+                        }
 
-                pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
-                workFields.push_back(pEHChield);
+                        ExpHistory* pEHChield = new ExpHistory(pEH,
+                                                               (*iterFields)->getExp(),
+                                                               (*iterFields)->getArgs(),
+                                                               (*iterFields)->getLevel(),
+                                                               (*iterFields)->isCellExp(),
+                                                               pIT);
+                        pEHChield->setWhereReinsert(iList);
+                        workFields.push_back(pEHChield);
+                    }
 
-                if (bReinsert)
-                {
-                    pEHChield->setReinsertion();
+                    pLOut->killMe();
                 }
             }
-        }
-        else if (pITCurrent->isList())
-        {
-            List* pL = pITCurrent->getAs<List>();
-            if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
+            else if (pITCurrent->isTList() || pITCurrent->isMList())
             {
-                // pITCurrent is an extraction of other Type
-                for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
+                TList* pTL = pITCurrent->getAs<TList>();
+                typed_list* pArgs = pEH->getArgs();
+                if (pArgs)
                 {
-                    ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
-                    pEHExtract->setWhereReinsert(iLoop);
-                    workFields.push_front(pEHExtract);
-                }
-            }
-            else
-            {
-                // pITCurrent is a field
-                if (pEH->getArgs())
-                {
-                    if (pEH->getArgs()->size() > 1)
+                    if (pArgs->size() > 1 || pITCurrent->isMList())
                     {
                         // call overload
-                        InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
-
+                        InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
                         if ((*iterFields)->getExp() == NULL)
                         {
                             // a(x)(y)
-                            // extract a(x) and push_BACK to extract next level
+                            // 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();
                         }
                     }
                     else
                     {
-                        // resize List
+                        // resize TList
                         int iNewSize = pEH->getSizeFromArgs();
-                        if (pL->getSize() < iNewSize)
+                        if (pTL->getSize() < iNewSize)
                         {
-                            pL->set(iNewSize - 1, new ListUndefined());
+                            pTL->set(iNewSize - 1, new ListUndefined());
                         }
 
-                        Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
-                        double* pdblArgs = pDblArgs->get();
+                        // 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();
 
                         if ((*iterFields)->getExp() == NULL)
                         {
-                            // a(x)(y) => a.b(y)
-                            // extract a(x) and push_BACK to extract next level
-                            for (int iLoop = 0; iLoop < pDblArgs->getSize(); 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(), pL->get((int)pdblArgs[iLoop] - 1));
-                                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 (int iLoop = 0; iLoop < pDblArgs->getSize(); 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(), pL->get((int)pdblArgs[iLoop] - 1));
-                                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);
                             }
                         }
@@ -1044,418 +960,554 @@ types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*
                 }
                 else
                 {
-                    // a.x, get string "x"
-                    std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+                    // get string "x" of a.x
+                    InternalType* pExtract = NULL;
+                    std::wstring pwcsFieldname = L"";
+                    bool bReinsert = false;
+                    ExpHistory* pEHChield = NULL;
 
-                    // call overload
-                    typed_list* args = new typed_list();
-                    args->push_back(new String(pwcsFieldname.c_str()));
-                    pEH->setArgs(args);
+                    pwcsFieldname = (*iterFields)->getExpAsString();
 
-                    InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
+                    // check if field exists
+                    if (pTL->exists(pwcsFieldname) == false)
+                    {
+                        std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
+                        ++iterFieldsNext;
 
-                    // append extraction of a.x for next level.
-                    workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
-                    workFields.back()->setReinsertion();
-                }
-            }
-        }
-        else if (pITCurrent->isHandle())
-        {
-            // call overload
-            if (pEH->getArgs())
-            {
-                // call overload
-                InternalType* pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
+                        if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
+                        {
+                            // M=mlist(['MType','x','y'], ...
+                            // M.rows1 = "somthing"
+                            pArgs = new typed_list();
+                            pArgs->push_back(new String(pwcsFieldname.c_str()));
 
-                if ((*iterFields)->getExp() == NULL)
-                {
-                    // a(x)(y)
-                    // extract a(x) and push_BACK to extract next level
-                    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)
-                    workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
-                    workFields.front()->setReinsertion();
-                }
-            }
-            else
-            {
-                // a.x, get string "x"
-                std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+                            // call overload
+                            pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
+                            bReinsert = true;
 
-                // create arg with next field
-                typed_list* args = new typed_list();
-                args->push_back(new String(pwcsFieldname.c_str()));
-                pEH->setArgs(args);
+                            delete pArgs;
+                        }
+                    }
+                    else
+                    {
+                        // extract field x and append it to elements for next recursion.
+                        pExtract = pTL->getField(pwcsFieldname);
+                    }
 
-                // call overload
-                InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
+                    pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
+                    workFields.push_back(pEHChield);
 
-                // 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();
+                    if (bReinsert)
+                    {
+                        pEHChield->setReinsertion();
+                    }
+                }
             }
-        }
-        else if (pITCurrent->isCell())
-        {
-            Cell* pCell = pITCurrent->getAs<Cell>();
-            if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
+            else if (pITCurrent->isList())
             {
-                if (pEH->isCellExp())
+                List* pL = pITCurrent->getAs<List>();
+                if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
                 {
-                    // a{x} => extract like a(x){[1 2 ...]}
-                    if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
+                    // pITCurrent is an extraction of other Type
+                    for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
                     {
-                        // extract each elements of a(x)
-                        for (int iCell = 0; iCell < pCell->getSize(); iCell++)
+                        ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
+                        pEHExtract->setWhereReinsert(iLoop);
+                        workFields.push_front(pEHExtract);
+                    }
+                }
+                else
+                {
+                    // pITCurrent is a field
+                    if (pEH->getArgs())
+                    {
+                        if (pEH->getArgs()->size() > 1)
                         {
-                            InternalType* pIT = pCell->get(iCell);
+                            // call overload
+                            InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
+
                             if ((*iterFields)->getExp() == NULL)
                             {
-                                // a{x}(y)
-                                ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
-                                pEHChield->setWhereReinsert(iCell);
-                                workFields.push_back(pEHChield);
+                                // a(x)(y)
+                                // extract a(x) and push_BACK to extract next level
+                                workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
+                                workFields.back()->setReinsertion();
                             }
                             else
                             {
-                                // a{x}.b
-                                ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
-                                pEHChield->setWhereReinsert(iCell);
-                                workFields.push_front(pEHChield);
+                                // a(x).b
+                                // extract a(x) and push_FRONT to extract b from a(x)
+                                workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
+                                workFields.front()->setReinsertion();
                             }
                         }
-                    }
-                    else
-                    {
-                        if (pEH->needResize())
+                        else
                         {
-                            if (pEH->getArgsDims() == 1)
+                            // resize List
+                            int iNewSize = pEH->getSizeFromArgs();
+                            if (pL->getSize() < iNewSize)
                             {
-                                std::wostringstream os;
-                                os << _W("Invalid index.");
-                                throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                                pL->set(iNewSize - 1, new ListUndefined());
                             }
 
-                            // resize current Cell
-                            pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
-                        }
+                            Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
+                            double* pdblArgs = pDblArgs->get();
 
-                        InternalType* pIT = pCell->extract(pEH->getArgs());
-                        workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
-                        workFields.front()->setReinsertion();
-                    }
-                }
-                else
-                {
-                    if ((*iterFields)->isCellExp())
-                    {
-                        // a(x){y}
-                        if (pEH->needResize())
-                        {
-                            if (pEH->getArgsDims() == 1)
+                            if ((*iterFields)->getExp() == NULL)
                             {
-                                std::wostringstream os;
-                                os << _W("Invalid index.");
-                                throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                                // a(x)(y) => a.b(y)
+                                // extract a(x) and push_BACK to extract next level
+                                for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
+                                {
+                                    ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
+                                    pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
+                                    workFields.push_back(pEHExtract);
+                                }
+                            }
+                            else
+                            {
+                                // a(x).b
+                                // extract a(x) and push_FRONT to extract b from a(x)
+                                for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
+                                {
+                                    ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
+                                    pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
+                                    workFields.push_front(pEHExtract);
+                                }
                             }
-
-                            // resize current Cell
-                            pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
                         }
-
-                        InternalType* pIT = pCell->extract(pEH->getArgs());
-                        workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
-                        workFields.front()->setReinsertion();
                     }
                     else
                     {
-                        // only a(x)
-                        std::wostringstream os;
-                        os << _W("Wrong insertion in a Cell.");
-                        throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        // a.x, get string "x"
+                        std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+
+                        // call overload
+                        typed_list* args = new typed_list();
+                        args->push_back(new String(pwcsFieldname.c_str()));
+                        pEH->setArgs(args);
+
+                        InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, 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.back()->setReinsertion();
                     }
                 }
             }
-            else
+            else if (pITCurrent->isHandle())
             {
-                std::wostringstream os;
-                os << _W("Wrong insertion in a Cell.");
-                throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
-            }
-        }
-        else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
-        {
-            // call userType extract method
-            if (pEH->getArgs())
-            {
-                // a(x)
-                InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(pEH->getArgs());
-                if (pExtract == NULL)
+                // call overload
+                if (pEH->getArgs())
                 {
                     // call overload
-                    pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
-                }
+                    InternalType* pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
 
-                if ((*iterFields)->getExp() == NULL)
-                {
-                    // a(x)(y)
-                    // extract a(x) and push_BACK to extract next level
-                    workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
-                    workFields.back()->setReinsertion();
+                    if ((*iterFields)->getExp() == NULL)
+                    {
+                        // a(x)(y)
+                        // extract a(x) and push_BACK to extract next level
+                        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)
+                        workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
+                        workFields.front()->setReinsertion();
+                    }
                 }
                 else
                 {
-                    // a(x).b
-                    // extract a(x) and push_FRONT to extract b from a(x)
-                    workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
-                    workFields.front()->setReinsertion();
-                }
-            }
-            else
-            {
-                // a.x, get string "x"
-                std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
+                    // 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);
+                    // 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);
-                }
+                    InternalType* 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();
+                    // 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();
+            else if (pITCurrent->isCell())
+            {
+                Cell* pCell = pITCurrent->getAs<Cell>();
+                if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
+                {
+                    if (pEH->isCellExp())
+                    {
+                        // a{x} => extract like a(x){[1 2 ...]}
+                        if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
+                        {
+                            // extract each elements of a(x)
+                            for (int iCell = 0; iCell < pCell->getSize(); iCell++)
+                            {
+                                InternalType* pIT = pCell->get(iCell);
+                                if ((*iterFields)->getExp() == NULL)
+                                {
+                                    // a{x}(y)
+                                    ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
+                                    pEHChield->setWhereReinsert(iCell);
+                                    workFields.push_back(pEHChield);
+                                }
+                                else
+                                {
+                                    // a{x}.b
+                                    ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
+                                    pEHChield->setWhereReinsert(iCell);
+                                    workFields.push_front(pEHChield);
+                                }
+                            }
+                        }
+                        else
+                        {
+                            if (pEH->needResize())
+                            {
+                                if (pEH->getArgsDims() == 1)
+                                {
+                                    std::wostringstream os;
+                                    os << _W("Invalid index.");
+                                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                                }
 
-            workFields.push_front(pEH);
-            evalFields.pop_back();
-        }
+                                // resize current Cell
+                                pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
+                            }
 
-        if (workFields.front()->getLevel() == (*iterFields)->getLevel())
-        {
-            // go to next field
-            iterFields++;
-        }
-    }
+                            InternalType* pIT = pCell->extract(pEH->getArgs());
+                            workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
+                            workFields.front()->setReinsertion();
+                        }
+                    }
+                    else
+                    {
+                        if ((*iterFields)->isCellExp())
+                        {
+                            // a(x){y}
+                            if (pEH->needResize())
+                            {
+                                if (pEH->getArgsDims() == 1)
+                                {
+                                    std::wostringstream os;
+                                    os << _W("Invalid index.");
+                                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                                }
 
-    //*** insert what we have to assign ***//
-    while (workFields.empty() == false)
-    {
-        ExpHistory* pEH = workFields.front();
-        evalFields.push_back(pEH);
-        workFields.pop_front();
+                                // resize current Cell
+                                pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
+                            }
 
-        if (pEH->getArgs())
-        {
-            typed_list* pArgs = pEH->getArgs();
-            if (pEH->isCellExp())
-            {
-                Cell* pCell = pEH->getCurrent()->getAs<Cell>();
-                // insert "something" in b{x}
-                if ((*pArgs)[0]->isString())
+                            InternalType* pIT = pCell->extract(pEH->getArgs());
+                            workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
+                            workFields.front()->setReinsertion();
+                        }
+                        else
+                        {
+                            // only a(x)
+                            std::wostringstream os;
+                            os << _W("Wrong insertion in a Cell.");
+                            throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        }
+                    }
+                }
+                else
                 {
                     std::wostringstream os;
                     os << _W("Wrong insertion in a Cell.");
                     throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
                 }
-
-                pCell->insertCell(pArgs, _pAssignValue);
             }
-            else
+            else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
             {
-                // insert "something" in b(x,y)
-                InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
-                if (pIT == NULL)
+                // call userType extract method
+                if (pEH->getArgs())
                 {
-                    std::wostringstream os;
-                    os << _W("Submatrix incorrectly defined.");
-                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
-                }
+                    // 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);
+                    }
 
-                if (pEH->setCurrent(pIT))
+                    if ((*iterFields)->getExp() == NULL)
+                    {
+                        // a(x)(y)
+                        // extract a(x) and push_BACK to extract next level
+                        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)
+                        workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
+                        workFields.front()->setReinsertion();
+                    }
+                }
+                else
                 {
-                    pEH->setReinsertion();
+                    // 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())
+            {
+                // go to next field
+                iterFields++;
+            }
         }
-        else
+
+        //*** insert what we have to assign ***//
+        while (workFields.empty() == false)
         {
-            InternalType* pParent = pEH->getParent()->getCurrent();
-            if (pParent->isStruct())
+            ExpHistory* pEH = workFields.front();
+            evalFields.push_back(pEH);
+            workFields.pop_front();
+
+            if (pEH->getArgs())
             {
-                Struct* pStruct = pParent->getAs<Struct>();
-                if (_pAssignValue->isListDelete())
+                typed_list* pArgs = pEH->getArgs();
+                if (pEH->isCellExp())
                 {
-                    pStruct->removeField(pEH->getExpAsString());
+                    Cell* pCell = pEH->getCurrent()->getAs<Cell>();
+                    // insert "something" in b{x}
+                    if ((*pArgs)[0]->isString())
+                    {
+                        std::wostringstream os;
+                        os << _W("Wrong insertion in a Cell.");
+                        throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                    }
+
+                    pCell->insertCell(pArgs, _pAssignValue);
                 }
                 else
                 {
-                    pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), _pAssignValue);
-                }
+                    // insert "something" in b(x,y)
+                    InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
+                    if (pIT == NULL)
+                    {
+                        std::wostringstream os;
+                        os << _W("Submatrix incorrectly defined.");
+                        throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                    }
 
-                // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
-                delete pEH;
-                evalFields.pop_back();
+                    if (pEH->setCurrent(pIT))
+                    {
+                        pEH->setReinsertion();
+                    }
+                }
             }
-            else if (pParent->isTList() || pParent->isMList())
+            else
             {
-                TList* pTL = pParent->getAs<TList>();
-                if (_pAssignValue->isListDelete() || (pTL->exists(pEH->getExpAsString()) == false))
+                InternalType* pParent = pEH->getParent()->getCurrent();
+                if (pParent->isStruct())
                 {
-                    typed_list args;
-                    args.push_back(new String(pEH->getExpAsString().c_str()));
-                    InternalType* pIT = insertionCall(*_pExp, &args, pEH->getParent()->getCurrent(), _pAssignValue);
-                    if (pIT == NULL)
+                    Struct* pStruct = pParent->getAs<Struct>();
+                    if (_pAssignValue->isListDelete())
                     {
-                        std::wostringstream os;
-                        os << _W("Error in insertion of TList.");
-                        throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        pStruct->removeField(pEH->getExpAsString());
+                    }
+                    else
+                    {
+                        pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), _pAssignValue);
                     }
 
-                    if (pEH->getParent()->setCurrent(pIT))
+                    // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
+                    delete pEH;
+                    evalFields.pop_back();
+                }
+                else if (pParent->isTList() || pParent->isMList())
+                {
+                    TList* pTL = pParent->getAs<TList>();
+                    if (_pAssignValue->isListDelete() || (pTL->exists(pEH->getExpAsString()) == false))
+                    {
+                        typed_list args;
+                        args.push_back(new String(pEH->getExpAsString().c_str()));
+                        InternalType* pIT = insertionCall(*_pExp, &args, pEH->getParent()->getCurrent(), _pAssignValue);
+                        if (pIT == NULL)
+                        {
+                            std::wostringstream os;
+                            os << _W("Error in insertion of TList.");
+                            throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                        }
+
+                        if (pEH->getParent()->setCurrent(pIT))
+                        {
+                            pEH->getParent()->setReinsertion();
+                            pEH->resetReinsertion();
+                        }
+                    }
+                    else
                     {
-                        pEH->getParent()->setReinsertion();
-                        pEH->resetReinsertion();
+                        pTL->set(pEH->getExpAsString(), _pAssignValue);
                     }
+
+                    // set _pAssignValue in parent, so kill the current if needed
+                    // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
+                    delete pEH;
+                    evalFields.pop_back();
                 }
                 else
                 {
-                    pTL->set(pEH->getExpAsString(), _pAssignValue);
+                    pEH->setCurrent(_pAssignValue);
+                    pEH->setReinsertion();
                 }
-
-                // set _pAssignValue in parent, so kill the current if needed
-                // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
-                delete pEH;
-                evalFields.pop_back();
-            }
-            else
-            {
-                pEH->setCurrent(_pAssignValue);
-                pEH->setReinsertion();
             }
         }
-    }
 
-    //*** update fields ***//
-    while (evalFields.empty() == false)
-    {
-        ExpHistory* pEH = evalFields.back();
-        if (pEH->reinsertMe())
+        //*** update fields ***//
+        while (evalFields.empty() == false)
         {
-            ExpHistory* pEHParent = pEH->getParent();
-
-            if (pEHParent == NULL)
+            ExpHistory* pEH = evalFields.back();
+            if (pEH->reinsertMe())
             {
-                symbol::Context::getInstance()->put(pEH->getExp()->getStack(), pEH->getCurrent());
-                break;
-            }
+                ExpHistory* pEHParent = pEH->getParent();
 
-            typed_list* pParentArgs = pEHParent->getArgs();
-            if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
-            {
-                InternalType* pParent = pEHParent->getCurrent();
-                if (pParent->isStruct())
+                if (pEHParent == NULL)
                 {
-                    Struct* pStruct = pParent->getAs<Struct>();
-                    pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
-                    evalFields.pop_back();
-                    delete pEH;
-                    continue;
+                    symbol::Context::getInstance()->put(pEH->getExp()->getStack(), pEH->getCurrent());
+                    break;
                 }
-                else if (pParent->isTList() || pParent->isMList())
+
+                typed_list* pParentArgs = pEHParent->getArgs();
+                if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
                 {
-                    TList* pTL = pParent->getAs<TList>();
-                    if (pParentArgs)
+                    InternalType* pParent = pEHParent->getCurrent();
+                    if (pParent->isStruct())
                     {
-                        pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
+                        Struct* pStruct = pParent->getAs<Struct>();
+                        pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
                         evalFields.pop_back();
                         delete pEH;
                         continue;
                     }
-                    else
+                    else if (pParent->isTList() || pParent->isMList())
                     {
-                        if (pTL->exists(pEH->getExpAsString()))
+                        TList* pTL = pParent->getAs<TList>();
+                        if (pParentArgs)
                         {
-                            pTL->set(pEH->getExpAsString(), pEH->getCurrent());
+                            pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
                             evalFields.pop_back();
                             delete pEH;
                             continue;
                         }
+                        else
+                        {
+                            if (pTL->exists(pEH->getExpAsString()))
+                            {
+                                pTL->set(pEH->getExpAsString(), pEH->getCurrent());
+                                evalFields.pop_back();
+                                delete pEH;
+                                continue;
+                            }
 
-                        pParentArgs = new typed_list();
-                        pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
+                            pParentArgs = new typed_list();
+                            pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
+                        }
                     }
-                }
-                else if (pParent->isCell())
-                {
-                    Cell* pCell = pParent->getAs<Cell>();
-                    if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
+                    else if (pParent->isCell())
                     {
-                        // a{x}.b => reinsert b in a{x}
-                        pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
-                        pEHParent->setReinsertion();
-                        evalFields.pop_back();
-                        delete pEH;
-                        continue;
+                        Cell* pCell = pParent->getAs<Cell>();
+                        if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
+                        {
+                            // a{x}.b => reinsert b in a{x}
+                            pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
+                            pEHParent->setReinsertion();
+                            evalFields.pop_back();
+                            delete pEH;
+                            continue;
+                        }
                     }
                 }
-            }
 
-            InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
-            if (pIT == NULL)
-            {
-                std::wostringstream os;
-                os << _W("Submatrix incorrectly defined.");
-                throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
-            }
+                InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
+                if (pIT == NULL)
+                {
+                    std::wostringstream os;
+                    os << _W("Submatrix incorrectly defined.");
+                    throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
+                }
 
-            if (pEHParent->setCurrent(pIT))
-            {
-                pEHParent->setReinsertion();
+                if (pEHParent->setCurrent(pIT))
+                {
+                    pEHParent->setReinsertion();
+                }
+
+                if (pEHParent->getArgs() == NULL)
+                {
+                    delete pParentArgs;
+                }
             }
 
-            if (pEHParent->getArgs() == NULL)
+            if (pEH->getCurrent())
             {
-                delete pParentArgs;
+                pEH->getCurrent()->killMe();
             }
+
+            evalFields.pop_back();
+            delete pEH;
         }
 
-        if (pEH->getCurrent())
+        if (!evalFields.empty())
         {
-            pEH->getCurrent()->killMe();
+            for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
+            {
+                delete *i;
+            }
         }
 
-        evalFields.pop_back();
-        delete pEH;
+        return symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
     }
-
-    if (!evalFields.empty())
+    catch (ast::ScilabError error)
     {
-        for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
+        for (std::list<ExpHistory*>::reverse_iterator i = workFields.rbegin(); i != workFields.rend(); ++i)
         {
+            (*i)->setDeleteCurrent(true);
+            delete *i;
+        }
+
+        for (std::list<ExpHistory*>::reverse_iterator i = evalFields.rbegin(); i != evalFields.rend(); ++i)
+        {
+            (*i)->setDeleteCurrent(true);
             delete *i;
         }
-    }
 
-    return symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
+        throw error;
+    }
 }
 
 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
index 637d3bc..957f906 100644 (file)
@@ -33,6 +33,9 @@ Cell::Cell()
     InternalType** pIT  = NULL;
     int piDims[2] = {0, 0};
     create(piDims, 2, &pIT, NULL);
+#ifndef NDEBUG
+    Inspector::addItem(this);
+#endif
 }
 
 Cell::Cell(int _iRows, int _iCols)
@@ -40,24 +43,18 @@ Cell::Cell(int _iRows, int _iCols)
     InternalType** pIT  = NULL;
     int piDims[2] = {_iRows, _iCols};
     create(piDims, 2, &pIT, NULL);
-    Double* pEmpty = Double::Empty();
-    for (int i = 0 ; i < getSize() ; i++)
-    {
-        pEmpty->IncreaseRef();
-        m_pRealData[i] = pEmpty;
-    }
+#ifndef NDEBUG
+    Inspector::addItem(this);
+#endif
 }
 
 Cell::Cell(int _iDims, int* _piDims)
 {
     InternalType** pIT  = NULL;
     create(_piDims, _iDims, &pIT, NULL);
-    Double* pEmpty = Double::Empty();
-    for (int i = 0 ; i < getSize() ; i++)
-    {
-        pEmpty->IncreaseRef();
-        m_pRealData[i] = pEmpty;
-    }
+#ifndef NDEBUG
+    Inspector::addItem(this);
+#endif
 }
 
 Cell::~Cell()
@@ -67,10 +64,7 @@ Cell::~Cell()
         for (int i = 0 ; i < getSize() ; i++)
         {
             m_pRealData[i]->DecreaseRef();
-            if (m_pRealData[i]->isDeletable())
-            {
-                delete m_pRealData[i];
-            }
+            m_pRealData[i]->killMe();
         }
     }
 #ifndef NDEBUG
@@ -153,10 +147,7 @@ bool Cell::set(int _iIndex, InternalType* _pIT)
         if (m_pRealData[_iIndex] != NULL)
         {
             m_pRealData[_iIndex]->DecreaseRef();
-            if (m_pRealData[_iIndex]->isDeletable())
-            {
-                delete m_pRealData[_iIndex];
-            }
+            m_pRealData[_iIndex]->killMe();
         }
 
         _pIT->IncreaseRef();
@@ -173,10 +164,7 @@ bool Cell::set(int _iIndex, const InternalType* _pIT)
         if (m_pRealData[_iIndex] != NULL)
         {
             m_pRealData[_iIndex]->DecreaseRef();
-            if (m_pRealData[_iIndex]->isDeletable())
-            {
-                delete m_pRealData[_iIndex];
-            }
+            m_pRealData[_iIndex]->killMe();
         }
 
         const_cast<InternalType*>(_pIT)->IncreaseRef();
@@ -228,11 +216,9 @@ void Cell::deleteAll()
     for (int i = 0 ; i < getSize() ; i++)
     {
         m_pRealData[i]->DecreaseRef();
-        if (m_pRealData[i]->isDeletable())
-        {
-            delete m_pRealData[i];
-        }
+        m_pRealData[i]->killMe();
     }
+
     delete[] m_pRealData;
     m_pRealData = NULL;
 }
@@ -286,7 +272,7 @@ bool Cell::subMatrixToString(std::wostringstream& ostr, int* _piDims, int /*_iDi
                 {
                     //compute number of digits to write dimensions
                     int iTypeLen = 0;
-                    if (pIT->getAs<GenericType>())
+                    if (pIT->isGenericType())
                     {
                         GenericType* pGT = pIT->getAs<GenericType>();
                         for (int k = 0 ; k < pGT->getDims() ; k++)
@@ -426,7 +412,7 @@ List* Cell::extractCell(typed_list* _pArgs)
     {
         pList->append(pCell->get(i));
     }
-    delete pCell;
+    pCell->killMe();
     return pList;
 }
 
@@ -435,6 +421,7 @@ Cell* Cell::insertCell(typed_list* _pArgs, InternalType* _pSource)
     Cell* pCell = new Cell(1, 1);
     pCell->set(0, _pSource);
     Cell* pOut = insert(_pArgs, pCell)->getAs<Cell>();
+    pCell->killMe();
     return pOut;
 }