2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
15 #include "visitor_common.hxx"
17 #include "fieldexp.hxx"
18 #include "simplevar.hxx"
19 #include "callexp.hxx"
21 #include "context.hxx"
22 #include "execvisitor.hxx"
23 #include "serializervisitor.hxx"
24 #include "deserializervisitor.hxx"
25 #include "localization.hxx"
28 #include "alltypes.hxx"
30 size_t ast::Ast::globalNodeNumber = 0;
33 * Generate destination variable from _poSource type and size parameters
35 types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _iCols)
37 types::InternalType* poResult = NULL;
38 switch (_poSource->getType())
40 case types::GenericType::ScilabDouble :
41 poResult = new types::Double(_iRows, _iCols, false);
43 case types::GenericType::ScilabBool :
44 poResult = new types::Bool(_iRows, _iCols);
46 case types::GenericType::ScilabInt8 :
47 poResult = new types::Int8(_iRows, _iCols);
49 case types::GenericType::ScilabUInt8 :
50 poResult = new types::UInt8(_iRows, _iCols);
52 case types::GenericType::ScilabInt16 :
53 poResult = new types::Int16(_iRows, _iCols);
55 case types::GenericType::ScilabUInt16 :
56 poResult = new types::UInt16(_iRows, _iCols);
58 case types::GenericType::ScilabInt32 :
59 poResult = new types::Int32(_iRows, _iCols);
61 case types::GenericType::ScilabUInt32 :
62 poResult = new types::UInt32(_iRows, _iCols);
64 case types::GenericType::ScilabInt64 :
65 poResult = new types::Int64(_iRows, _iCols);
67 case types::GenericType::ScilabUInt64 :
68 poResult = new types::UInt64(_iRows, _iCols);
70 case types::GenericType::ScilabString :
71 poResult = new types::String(_iRows, _iCols);
73 case types::GenericType::ScilabPolynom :
75 int* piRank = new int[_iRows * _iCols];
76 memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
77 poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
81 case types::InternalType::ScilabImplicitList :
82 poResult = new types::ImplicitList();
85 // FIXME : What should we do here ??
91 types::InternalType* AddElementToVariableFromCol(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piCols)
93 types::InternalType *poResult = NULL;
94 types::InternalType::ScilabType TypeSource = _poSource->getType();
95 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
99 //First call, alloc _poSource
100 poResult = allocDest(_poSource, _iRows, _iCols);
101 TypeDest = TypeSource;
105 TypeDest = _poDest->getType();
109 if (TypeDest != TypeSource)
111 //check if source type is compatible with dest type
117 case types::GenericType::ScilabDouble :
118 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
120 poResult->getAs<types::Double>()->setComplex(true);
123 poResult->getAs<types::Double>()->fillFromCol(*_piCols, _poSource->getAs<types::Double>());
124 *_piCols += _poSource->getAs<types::Double>()->getCols();
135 types::InternalType* AddElementToVariableFromRow(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piRows)
137 types::InternalType *poResult = NULL;
138 types::InternalType::ScilabType TypeSource = _poSource->getType();
139 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
143 //First call, alloc _poSource
144 poResult = allocDest(_poSource, _iRows, _iCols);
145 TypeDest = TypeSource;
149 TypeDest = _poDest->getType();
154 if (TypeDest != TypeSource)
156 //check if source type is compatible with dest type
162 case types::GenericType::ScilabDouble :
163 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
165 poResult->getAs<types::Double>()->setComplex(true);
168 poResult->getAs<types::Double>()->fillFromRow(*_piRows, _poSource->getAs<types::Double>());
169 *_piRows += _poSource->getAs<types::Double>()->getRows();
182 _iRows : Position if _poDest allready initialized else size of the matrix
183 _iCols : Position if _poDest allready initialized else size of the matrix
185 types::InternalType* AddElementToVariable(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols)
187 types::InternalType *poResult = NULL;
188 types::InternalType::ScilabType TypeSource = _poSource->getType();
189 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
190 int iCurRow = _iRows;
191 int iCurCol = _iCols;
197 case types::GenericType::ScilabDouble :
198 poResult = new types::Double(_iRows, _iCols, false);
200 case types::GenericType::ScilabBool :
201 poResult = new types::Bool(_iRows, _iCols);
203 case types::GenericType::ScilabInt8 :
204 poResult = new types::Int8(_iRows, _iCols);
206 case types::GenericType::ScilabUInt8 :
207 poResult = new types::UInt8(_iRows, _iCols);
209 case types::GenericType::ScilabInt16 :
210 poResult = new types::Int16(_iRows, _iCols);
212 case types::GenericType::ScilabUInt16 :
213 poResult = new types::UInt16(_iRows, _iCols);
215 case types::GenericType::ScilabInt32 :
216 poResult = new types::Int32(_iRows, _iCols);
218 case types::GenericType::ScilabUInt32 :
219 poResult = new types::UInt32(_iRows, _iCols);
221 case types::GenericType::ScilabInt64 :
222 poResult = new types::Int64(_iRows, _iCols);
224 case types::GenericType::ScilabUInt64 :
225 poResult = new types::UInt64(_iRows, _iCols);
227 case types::GenericType::ScilabString :
228 poResult = new types::String(_iRows, _iCols);
230 case types::GenericType::ScilabSparse :
231 poResult = new types::Sparse(_iRows, _iCols);
233 case types::GenericType::ScilabSparseBool :
234 poResult = new types::SparseBool(_iRows, _iCols);
236 case types::GenericType::ScilabPolynom :
238 int* piRank = new int[_iRows * _iCols];
239 memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
240 poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
244 case types::InternalType::ScilabImplicitList :
245 poResult = new types::ImplicitList();
247 case types::GenericType::ScilabHandle :
248 poResult = new types::GraphicHandle(_iRows, _iCols);
251 // FIXME What should we do here ...
256 TypeDest = TypeSource;
260 TypeDest = _poDest->getType();
265 if (TypeDest != TypeSource)
267 //check if source type is compatible with dest type
270 case types::GenericType::ScilabDouble :
271 if (TypeSource == types::GenericType::ScilabPolynom)
273 types::Double *poDest = _poDest->getAs<types::Double>();
274 Polynom* pPSource = _poSource->getAs<types::Polynom>();
276 //Convert Dest to ScilabPolynom
277 int iSize = poDest->getSize();
278 int *piRank = new int[iSize];
279 memset(piRank, 0x00, iSize * sizeof(int));
280 poResult = new types::Polynom(pPSource->getVariableName(), poDest->getRows(), poDest->getCols(), piRank);
283 Polynom* pPResult = poResult->getAs<types::Polynom>();
284 pPResult->setComplex(poDest->isComplex());
286 double *pR = poDest->getReal();
287 SinglePoly** pSP = pPResult->get();
289 if (poDest->isComplex())
291 double *pI = poDest->getImg();
292 for (int i = 0 ; i < iSize; i++)
294 pSP[i]->set(0, pR[i]);
295 pSP[i]->setImg(0, pI[i]);
300 for (int i = 0 ; i < iSize; i++)
302 pSP[i]->set(0, pR[i]);
306 for (int i = 0 ; i < pPSource->getRows() ; i++)
308 for (int j = 0 ; j < pPSource->getCols() ; j++)
310 pPResult->set(iCurRow + i, iCurCol + j, pPSource->get(i, j));
317 case types::GenericType::ScilabPolynom :
318 if (TypeSource == types::GenericType::ScilabDouble)
320 //Add Source like coef of the new element
321 Double* pD = _poSource->getAs<Double>();
322 types::Polynom* pPolyOut = poResult->getAs<types::Polynom>();
326 pPolyOut->setComplex(true);
327 for (int i = 0 ; i < pD->getRows() ; i++)
329 for (int j = 0 ; j < pD->getCols() ; j++)
331 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
334 double pDblR = pD->get(i, j);
335 double pDblI = pD->getImg(i, j);
336 pSPOut->setCoef(&pDblR, &pDblI);
342 for (int i = 0 ; i < pD->getRows() ; i++)
344 for (int j = 0 ; j < pD->getCols() ; j++)
346 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
349 double pDbl = pD->get(i, j);
350 pSPOut->setCoef(&pDbl, NULL);
358 case types::GenericType::ScilabSparse :
359 if (TypeSource == types::GenericType::ScilabDouble)
361 types::Double* poSource = _poSource->getAs<types::Double>();
362 types::Sparse* spResult = poResult->getAs<types::Sparse>();
364 // Set complex the result if one of inputs is complex
365 if (poSource->isComplex())
367 if (spResult->isComplex() == false)
369 spResult->toComplex();
373 // Add poSource at the end of spResult
374 if (spResult->isComplex())
376 if (poSource->isComplex())
378 for (int i = 0; i < poSource->getRows(); i++)
380 for (int j = 0; j < poSource->getCols(); j++)
382 double dbl = poSource->get(i, j);
383 double dblImg = poSource->getImg(i, j);
384 if (dbl != 0 || dblImg != 0)
386 spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, dblImg));
393 for (int i = 0; i < poSource->getRows(); i++)
395 for (int j = 0; j < poSource->getCols(); j++)
397 double dbl = poSource->get(i, j);
400 spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, 0));
408 for (int i = 0; i < poSource->getRows(); i++)
410 for (int j = 0; j < poSource->getCols(); j++)
412 double dbl = poSource->get(i, j);
415 spResult->set(i + iCurRow, j + iCurCol, dbl);
424 case types::GenericType::ScilabSparseBool :
425 if (TypeSource == types::GenericType::ScilabBool)
427 types::Bool* poSource = _poSource->getAs<types::Bool>();
428 types::SparseBool* spResult = poResult->getAs<types::SparseBool>();
430 // Add poSource at the end of spResult
431 for (int i = 0; i < poSource->getRows(); i++)
433 for (int j = 0; j < poSource->getCols(); j++)
435 bool bValue = poSource->get(i, j) != 0;
438 spResult->set(i + iCurRow, j + iCurCol, true);
454 //Just add the new value in the current item
457 case types::GenericType::ScilabDouble :
458 ((Double*)poResult)->append(iCurRow, iCurCol, (Double*)_poSource);
460 case types::GenericType::ScilabPolynom :
461 poResult->getAs<types::Polynom>()->append(iCurRow, iCurCol, _poSource->getAs<types::Polynom>());
463 case types::GenericType::ScilabBool:
464 poResult->getAs<types::Bool>()->append(iCurRow, iCurCol, _poSource->getAs<types::Bool>());
466 case types::GenericType::ScilabInt8 :
467 poResult->getAs<types::Int8>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int8>());
469 case types::GenericType::ScilabUInt8 :
470 poResult->getAs<types::UInt8>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt8>());
472 case types::GenericType::ScilabInt16 :
473 poResult->getAs<types::Int16>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int16>());
475 case types::GenericType::ScilabUInt16 :
476 poResult->getAs<types::UInt16>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt16>());
478 case types::GenericType::ScilabInt32 :
479 poResult->getAs<types::Int32>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int32>());
481 case types::GenericType::ScilabUInt32 :
482 poResult->getAs<types::UInt32>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt32>());
484 case types::GenericType::ScilabInt64 :
485 poResult->getAs<types::Int64>()->append(iCurRow, iCurCol, _poSource->getAs<types::Int64>());
487 case types::GenericType::ScilabUInt64 :
488 poResult->getAs<types::UInt64>()->append(iCurRow, iCurCol, _poSource->getAs<types::UInt64>());
490 case types::GenericType::ScilabSparse :
491 poResult->getAs<types::Sparse>()->append(iCurRow, iCurCol, _poSource->getAs<types::Sparse>());
493 case types::GenericType::ScilabSparseBool :
494 poResult->getAs<types::SparseBool>()->append(iCurRow, iCurCol, _poSource->getAs<types::SparseBool>());
496 case types::GenericType::ScilabString :
498 types::String* pSource = _poSource->getAs<types::String>();
499 poResult->getAs<types::String>()->append(iCurRow, iCurCol, pSource);
502 case types::GenericType::ScilabImplicitList :
504 if (_poSource->getAs<ImplicitList>()->getStartType() == types::InternalType::ScilabPolynom)
506 poResult->getAs<ImplicitList>()->setStart(_poSource->getAs<ImplicitList>()->getStart());
510 poResult->getAs<ImplicitList>()->setStart(_poSource->getAs<ImplicitList>()->getStart());
513 if (_poSource->getAs<ImplicitList>()->getStepType() == types::InternalType::ScilabPolynom)
515 poResult->getAs<ImplicitList>()->setStep(_poSource->getAs<ImplicitList>()->getStep());
519 poResult->getAs<ImplicitList>()->setStep(_poSource->getAs<ImplicitList>()->getStep());
522 if (_poSource->getAs<ImplicitList>()->getEndType() == types::InternalType::ScilabPolynom)
524 poResult->getAs<ImplicitList>()->setEnd(_poSource->getAs<ImplicitList>()->getEnd());
528 poResult->getAs<ImplicitList>()->setEnd(_poSource->getAs<ImplicitList>()->getEnd());
532 case types::GenericType::ScilabHandle :
533 poResult->getAs<types::GraphicHandle>()->append(iCurRow, iCurCol, _poSource->getAs<types::GraphicHandle>());
543 const std::wstring* getStructNameFromExp(const ast::Exp* _pExp)
545 const ast::FieldExp* pField = dynamic_cast<const ast::FieldExp*>(_pExp);
546 const ast::SimpleVar* pVar = dynamic_cast<const ast::SimpleVar*>(_pExp);
547 const ast::CallExp* pCall = dynamic_cast<const ast::CallExp*>(_pExp);
551 return getStructNameFromExp(pField->getHead());
555 return &(pVar->getSymbol().getName());
559 return getStructNameFromExp(&(pCall->getName()));
563 std::wostringstream os;
564 os << _W("Unknow expression");
565 //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
566 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
571 /*** overload insertion || extraction ***/
572 //%x_i_x(i1, i2, ..., in, source, dest) || %x_e(i1, i2, ..., in, source, dest)
573 //i1, ..., in : indexes
574 //dest : variable where insert data || NULL
575 //source : data to insert || extract indexes from source
576 types::InternalType* callOverload(const ast::Exp& e, std::wstring _strType, types::typed_list* _pArgs, types::InternalType* _source, types::InternalType* _dest)
578 types::Function::ReturnValue ret = types::Function::Error;
579 types::InternalType* pITOut = NULL;
580 types::typed_list in;
581 types::typed_list out;
583 std::wstring function_name;
584 function_name = L"%" + _source->getShortTypeStr() + L"_" + _strType;
586 for (int i = 0; i < (int)_pArgs->size(); i++)
588 (*_pArgs)[i]->IncreaseRef();
589 in.push_back((*_pArgs)[i]);
592 _source->IncreaseRef();
593 in.push_back(_source);
597 _dest->IncreaseRef();
600 function_name += L"_" + _dest->getShortTypeStr();
603 InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
604 // if %type_6 doesn't exist, call %l_6
605 if (_dest == NULL && pFunc == NULL)
607 function_name = L"%l_" + _strType;
610 // For insertion in TList, call normal insertion if overload doesn't exits
611 if ((_dest && _dest->isTList() && pFunc == NULL) == false || _source->isListDelete())
615 ast::ExecVisitor exec;
619 ret = Overload::call(function_name, in, 1, out, &exec);
621 catch (ast::ScilabError error)
627 if (ret == types::Function::Error)
629 for (int i = 0; i < (int)_pArgs->size(); i++)
631 (*_pArgs)[i]->DecreaseRef();
632 (*_pArgs)[i]->killMe();
635 _source->DecreaseRef();
639 _dest->DecreaseRef();
649 std::wostringstream os;
650 os << _W("Error in overload function: ") << function_name << std::endl;
651 throw ast::ScilabError(os.str(), 999, e.getLocation());
655 for (int i = 0; i < (int)_pArgs->size(); i++)
657 (*_pArgs)[i]->DecreaseRef();
660 _source->DecreaseRef();
663 _dest->DecreaseRef();
670 else if (out.size() > 1)
672 List* pListOut = new List();
673 for (int i = 0; i < (int)out.size(); i++)
675 pListOut->append(out[i]);
685 bool getFieldsFromExp(ast::Exp* _pExp, std::list<ExpHistory*>& fields)
687 ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(_pExp);
688 ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(_pExp);
689 ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(_pExp);
690 ast::CellCallExp* pCell = dynamic_cast<ast::CellCallExp*>(_pExp);
694 if (getFieldsFromExp(pField->getHead(), fields))
696 return getFieldsFromExp(pField->getTail(), fields);
705 fields.push_back(new ExpHistory(NULL, pVar));
709 ExpHistory * pEHParent = fields.back();
710 ExpHistory * pEH = new ExpHistory(pEHParent, pVar);
711 pEH->setLevel(pEHParent->getLevel() + 1);
712 fields.push_back(pEH);
719 ast::ExecVisitor execMe;
720 typed_list* pCurrentArgs = execMe.GetArgumentList(pCall->getArgs());
722 bool bErr = getFieldsFromExp(&pCall->getName(), fields);
724 pCurrentArgs->size() == 1 &&
725 (*pCurrentArgs)[0]->isString() &&
726 (*pCurrentArgs)[0]->getAs<String>()->getSize() == 1)
728 // a("b") => a.b or a(x)("b") => a(x).b
729 ExpHistory * pEHParent = fields.back();
730 ast::SimpleVar* pFieldVar = new ast::SimpleVar(pCall->getLocation(), *new symbol::Symbol((*pCurrentArgs)[0]->getAs<String>()->get(0)));
731 ExpHistory * pEH = new ExpHistory(pEHParent, pFieldVar);
732 pEH->setLevel(pEHParent->getLevel() + 1);
733 pEH->setExpOwner(true);
735 (*pCurrentArgs)[0]->killMe();
738 fields.push_back(pEH);
740 else if (fields.back()->getArgs())
743 ExpHistory * pEHParent = fields.back();
744 ExpHistory * pEH = new ExpHistory(pEHParent, pCurrentArgs);
745 pEH->setLevel(pEHParent->getLevel() + 1);
746 pEH->setArgsOwner(true);
747 fields.push_back(pEH);
752 fields.back()->setArgs(pCurrentArgs);
753 fields.back()->setArgsOwner(true);
759 fields.back()->setCellExp();
770 types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fields, InternalType* _pAssignValue)
772 std::list<ExpHistory*> evalFields;
773 std::list<ExpHistory*> workFields;
777 //*** get main variable ***//
778 std::list<ExpHistory*>::iterator iterFields = fields.begin();
779 ExpHistory* pFirstField = *iterFields;
780 InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
783 if (pFirstField->isCellExp())
785 // a{x}, where "a" doesn't exists
786 pIT = new Cell(1, 1);
787 symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
789 else if (fields.size() > 1)
792 //"a" does not exist or it is another type, create it with size 1,1 and return it
793 //create new structure variable
794 pIT = new Struct(1, 1);
795 symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
799 // a(x) = "something" and a does not exist
800 // a will be create in insertionCall
802 else if (pIT->getRef() > 1 && pIT->isHandle() == false)
805 symbol::Context::getInstance()->put(pFirstField->getExp()->getStack(), pIT);
807 else if (pIT == _pAssignValue)
809 // clone me before insert me in myself.
810 // ie : a.b = 2; a.b.c.d = a;
811 _pAssignValue = _pAssignValue->clone();
816 workFields.push_back(new ExpHistory(NULL,
817 pFirstField->getExp(),
818 pFirstField->getArgs(),
819 pFirstField->getLevel(),
820 pFirstField->isCellExp(),
823 //*** evaluate fields ***//
824 while (iterFields != fields.end())
826 ExpHistory* pEH = workFields.front();
827 evalFields.push_back(pEH);
828 workFields.pop_front();
830 types::InternalType* pITCurrent = pEH->getCurrent();
832 if (pEH->isCellExp() && pITCurrent->isCell() == false)
834 std::wostringstream os;
835 os << _W("Wrong insertion : use extraction with {} only on a Cell.");
836 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
839 if (pITCurrent->isStruct())
841 Struct* pStruct = pITCurrent->getAs<Struct>();
842 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
844 if (pEH->needResize())
846 if (pEH->getArgsDims() == 1)
848 std::wostringstream os;
849 os << _W("Invalid index.");
850 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
853 // resize current struct
854 pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
857 // create field in parent if it not exist
858 if (pStruct->exists(pwcsFieldname) == false)
860 pStruct->addField(pwcsFieldname);
865 InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
866 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
870 // extract field x and append it to elements for next recursion.
871 List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
872 for (int iList = 0; iList < pLOut->getSize(); iList++)
874 InternalType* pIT = pLOut->get(iList);
875 if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
877 // clone element before modify it.
878 //pIT->DecreaseRef();
880 pStruct->get(iList)->set(pwcsFieldname, pIT);
883 ExpHistory* pEHChield = new ExpHistory(pEH,
884 (*iterFields)->getExp(),
885 (*iterFields)->getArgs(),
886 (*iterFields)->getLevel(),
887 (*iterFields)->isCellExp(),
889 pEHChield->setWhereReinsert(iList);
890 workFields.push_back(pEHChield);
896 else if (pITCurrent->isTList() || pITCurrent->isMList())
898 TList* pTL = pITCurrent->getAs<TList>();
899 typed_list* pArgs = pEH->getArgs();
902 if (pArgs->size() > 1 || pITCurrent->isMList())
905 InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
906 if ((*iterFields)->getExp() == NULL)
909 // extract a(x) and push_BACK to extract y
910 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
911 workFields.back()->setReinsertion();
916 // extract a(x) and push_FRONT to extract b
917 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
918 workFields.front()->setReinsertion();
924 int iNewSize = pEH->getSizeFromArgs();
925 if (pTL->getSize() < iNewSize)
927 pTL->set(iNewSize - 1, new ListUndefined());
930 // update pArgs variables with new argument computed in getSizeFromArgs
931 pArgs = pEH->getArgs();
933 InternalType* pIT = pTL->extract(pArgs);
934 List* pList = pIT->getAs<List>();
935 double* pdblArgs = (*pArgs)[0]->getAs<Double>()->get();
937 if ((*iterFields)->getExp() == NULL)
940 // extract a(x) and push_BACK to extract y
941 for (int i = 0; i < pList->getSize(); i++)
943 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(i));
944 pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
945 workFields.push_back(pEHExtract);
951 // extract a(x) and push_FRONT to extract b
952 for (int i = 0; i < pList->getSize(); i++)
954 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(i));
955 pEHExtract->setWhereReinsert((int)(pdblArgs[i] - 1));
956 workFields.push_front(pEHExtract);
963 // get string "x" of a.x
964 InternalType* pExtract = NULL;
965 std::wstring pwcsFieldname = L"";
966 bool bReinsert = false;
967 ExpHistory* pEHChield = NULL;
969 pwcsFieldname = (*iterFields)->getExpAsString();
971 // check if field exists
972 if (pTL->exists(pwcsFieldname) == false)
974 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
977 if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
979 // M=mlist(['MType','x','y'], ...
980 // M.rows1 = "somthing"
981 pArgs = new typed_list();
982 pArgs->push_back(new String(pwcsFieldname.c_str()));
985 pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
993 // extract field x and append it to elements for next recursion.
994 pExtract = pTL->getField(pwcsFieldname);
997 pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
998 workFields.push_back(pEHChield);
1002 pEHChield->setReinsertion();
1006 else if (pITCurrent->isList())
1008 List* pL = pITCurrent->getAs<List>();
1009 if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
1011 // pITCurrent is an extraction of other Type
1012 for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
1014 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
1015 pEHExtract->setWhereReinsert(iLoop);
1016 workFields.push_front(pEHExtract);
1021 // pITCurrent is a field
1024 if (pEH->getArgs()->size() > 1)
1027 InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
1029 if ((*iterFields)->getExp() == NULL)
1032 // extract a(x) and push_BACK to extract next level
1033 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1034 workFields.back()->setReinsertion();
1039 // extract a(x) and push_FRONT to extract b from a(x)
1040 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1041 workFields.front()->setReinsertion();
1047 int iNewSize = pEH->getSizeFromArgs();
1048 if (pL->getSize() < iNewSize)
1050 pL->set(iNewSize - 1, new ListUndefined());
1053 Double* pDblArgs = (*pEH->getArgs())[0]->getAs<Double>();
1054 double* pdblArgs = pDblArgs->get();
1056 if ((*iterFields)->getExp() == NULL)
1058 // a(x)(y) => a.b(y)
1059 // extract a(x) and push_BACK to extract next level
1060 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1062 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1063 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1064 workFields.push_back(pEHExtract);
1070 // extract a(x) and push_FRONT to extract b from a(x)
1071 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1073 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1074 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1075 workFields.push_front(pEHExtract);
1082 // a.x, get string "x"
1083 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1086 typed_list* args = new typed_list();
1087 args->push_back(new String(pwcsFieldname.c_str()));
1090 InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
1092 // append extraction of a.x for next level.
1093 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1094 workFields.back()->setReinsertion();
1098 else if (pITCurrent->isHandle())
1104 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1106 if ((*iterFields)->getExp() == NULL)
1109 // extract a(x) and push_BACK to extract next level
1110 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1111 workFields.back()->setReinsertion();
1116 // extract a(x) and push_FRONT to extract b from a(x)
1117 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1118 workFields.front()->setReinsertion();
1123 // a.x, get string "x"
1124 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1126 // create arg with next field
1127 typed_list* args = new typed_list();
1128 args->push_back(new String(pwcsFieldname.c_str()));
1132 InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1134 // append extraction of a.x for next level.
1135 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1136 workFields.front()->setReinsertion();
1139 else if (pITCurrent->isCell())
1141 Cell* pCell = pITCurrent->getAs<Cell>();
1142 if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
1144 if (pEH->isCellExp())
1146 // a{x} => extract like a(x){[1 2 ...]}
1147 if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
1149 // extract each elements of a(x)
1150 for (int iCell = 0; iCell < pCell->getSize(); iCell++)
1152 InternalType* pIT = pCell->get(iCell);
1153 if ((*iterFields)->getExp() == NULL)
1156 ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
1157 pEHChield->setWhereReinsert(iCell);
1158 workFields.push_back(pEHChield);
1163 ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
1164 pEHChield->setWhereReinsert(iCell);
1165 workFields.push_front(pEHChield);
1171 if (pEH->needResize())
1173 if (pEH->getArgsDims() == 1)
1175 std::wostringstream os;
1176 os << _W("Invalid index.");
1177 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1180 // resize current Cell
1181 pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1184 InternalType* pIT = pCell->extract(pEH->getArgs());
1185 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
1186 workFields.front()->setReinsertion();
1191 if ((*iterFields)->isCellExp())
1194 if (pEH->needResize())
1196 if (pEH->getArgsDims() == 1)
1198 std::wostringstream os;
1199 os << _W("Invalid index.");
1200 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1203 // resize current Cell
1204 pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1207 InternalType* pIT = pCell->extract(pEH->getArgs());
1208 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
1209 workFields.front()->setReinsertion();
1214 std::wostringstream os;
1215 os << _W("Wrong insertion in a Cell.");
1216 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1222 std::wostringstream os;
1223 os << _W("Wrong insertion in a Cell.");
1224 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1227 else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
1229 // call userType extract method
1233 InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(pEH->getArgs());
1234 if (pExtract == NULL)
1237 pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1240 if ((*iterFields)->getExp() == NULL)
1243 // extract a(x) and push_BACK to extract next level
1244 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1245 workFields.back()->setReinsertion();
1250 // extract a(x) and push_FRONT to extract b from a(x)
1251 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1252 workFields.front()->setReinsertion();
1257 // a.x, get string "x"
1258 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1260 // create arg with next field
1261 typed_list* args = new typed_list();
1262 args->push_back(new String(pwcsFieldname.c_str()));
1265 InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(args);
1266 if (pExtract == NULL)
1269 pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1272 // append extraction of a.x for next level.
1273 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1274 workFields.front()->setReinsertion();
1279 InternalType* pIT = new Struct(1, 1);
1280 pEH->setCurrent(pIT);
1281 pEH->setReinsertion();
1283 workFields.push_front(pEH);
1284 evalFields.pop_back();
1287 if (workFields.front()->getLevel() == (*iterFields)->getLevel())
1294 //*** insert what we have to assign ***//
1295 while (workFields.empty() == false)
1297 ExpHistory* pEH = workFields.front();
1298 evalFields.push_back(pEH);
1299 workFields.pop_front();
1303 typed_list* pArgs = pEH->getArgs();
1304 if (pEH->isCellExp())
1306 Cell* pCell = pEH->getCurrent()->getAs<Cell>();
1307 // insert "something" in b{x}
1308 if ((*pArgs)[0]->isString())
1310 std::wostringstream os;
1311 os << _W("Wrong insertion in a Cell.");
1312 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1315 pCell->insertCell(pArgs, _pAssignValue);
1319 // insert "something" in b(x,y)
1320 InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
1323 std::wostringstream os;
1324 os << _W("Submatrix incorrectly defined.");
1325 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1328 if (pEH->setCurrent(pIT))
1330 pEH->setReinsertion();
1336 InternalType* pParent = pEH->getParent()->getCurrent();
1337 if (pParent->isStruct())
1339 Struct* pStruct = pParent->getAs<Struct>();
1340 if (_pAssignValue->isListDelete())
1342 pStruct->removeField(pEH->getExpAsString());
1346 pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), _pAssignValue);
1349 // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
1351 evalFields.pop_back();
1353 else if (pParent->isTList() || pParent->isMList())
1355 TList* pTL = pParent->getAs<TList>();
1356 if (_pAssignValue->isListDelete() || (pTL->exists(pEH->getExpAsString()) == false))
1359 args.push_back(new String(pEH->getExpAsString().c_str()));
1360 InternalType* pIT = insertionCall(*_pExp, &args, pEH->getParent()->getCurrent(), _pAssignValue);
1363 std::wostringstream os;
1364 os << _W("Error in insertion of TList.");
1365 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1368 if (pEH->getParent()->setCurrent(pIT))
1370 pEH->getParent()->setReinsertion();
1371 pEH->resetReinsertion();
1376 pTL->set(pEH->getExpAsString(), _pAssignValue);
1379 // set _pAssignValue in parent, so kill the current if needed
1380 // insert _pAssignValue in parent, delete PEh and removes it from list<ExpHistory*>
1382 evalFields.pop_back();
1386 pEH->setCurrent(_pAssignValue);
1387 pEH->setReinsertion();
1392 //*** update fields ***//
1393 while (evalFields.empty() == false)
1395 ExpHistory* pEH = evalFields.back();
1396 if (pEH->reinsertMe())
1398 ExpHistory* pEHParent = pEH->getParent();
1400 if (pEHParent == NULL)
1402 symbol::Context::getInstance()->put(pEH->getExp()->getStack(), pEH->getCurrent());
1406 typed_list* pParentArgs = pEHParent->getArgs();
1407 if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
1409 InternalType* pParent = pEHParent->getCurrent();
1410 if (pParent->isStruct())
1412 Struct* pStruct = pParent->getAs<Struct>();
1413 pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
1414 evalFields.pop_back();
1418 else if (pParent->isTList() || pParent->isMList())
1420 TList* pTL = pParent->getAs<TList>();
1423 pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
1424 evalFields.pop_back();
1430 if (pTL->exists(pEH->getExpAsString()))
1432 pTL->set(pEH->getExpAsString(), pEH->getCurrent());
1433 evalFields.pop_back();
1438 pParentArgs = new typed_list();
1439 pParentArgs->push_back(new String(pEH->getExpAsString().c_str()));
1442 else if (pParent->isCell())
1444 Cell* pCell = pParent->getAs<Cell>();
1445 if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
1447 // a{x}.b => reinsert b in a{x}
1448 pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
1449 pEHParent->setReinsertion();
1450 evalFields.pop_back();
1457 InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
1460 std::wostringstream os;
1461 os << _W("Submatrix incorrectly defined.");
1462 throw ast::ScilabError(os.str(), 999, _pExp->getLocation());
1465 if (pEHParent->setCurrent(pIT))
1467 pEHParent->setReinsertion();
1470 if (pEHParent->getArgs() == NULL)
1476 if (pEH->getCurrent())
1478 pEH->getCurrent()->killMe();
1481 evalFields.pop_back();
1485 if (!evalFields.empty())
1487 for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
1493 return symbol::Context::getInstance()->getCurrentLevel(pFirstField->getExp()->getSymbol());
1495 catch (ast::ScilabError error)
1497 for (std::list<ExpHistory*>::reverse_iterator i = workFields.rbegin(); i != workFields.rend(); ++i)
1499 (*i)->setDeleteCurrent(true);
1503 for (std::list<ExpHistory*>::reverse_iterator i = evalFields.rbegin(); i != evalFields.rend(); ++i)
1505 (*i)->setDeleteCurrent(true);
1513 InternalType* insertionCall(const ast::Exp& e, typed_list* _pArgs, InternalType* _pVar, InternalType* _pInsert)
1515 InternalType* pOut = NULL;
1516 InternalType *pIL = NULL;
1517 //fisrt extract implicit list
1518 if (_pInsert->isColon())
1520 //double* pdbl = NULL;
1521 //_pInsert = new Double(-1, -1, &pdbl);
1523 pIL = Double::Identity(-1, -1);
1527 else if (_pInsert->isImplicitList())
1529 pIL = _pInsert->getAs<ImplicitList>()->extractFullMatrix();
1530 if (pIL && pIL->isDeletable())
1536 else if (_pInsert->isContainer() && _pInsert->isRef())
1538 //std::cout << "assign container type during insertion" << std::endl;
1539 //InternalType* pIL = _pInsert->clone();
1543 if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar == NULL)
1545 // l(x) = [] when l is not defined => create l = []
1546 pOut = Double::Empty();
1548 else if (_pInsert->isDouble() && _pInsert->getAs<Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1550 //insert [] so deletion except for Struct and List which can insert []
1551 InternalType::ScilabType varType = _pVar->getType();
1554 case InternalType::ScilabDouble :
1556 pOut = _pVar->getAs<Double>()->remove(_pArgs);
1559 case InternalType::ScilabString :
1561 pOut = _pVar->getAs<String>()->remove(_pArgs);
1564 case InternalType::ScilabCell :
1566 pOut = _pVar->getAs<Cell>()->remove(_pArgs);
1569 case InternalType::ScilabBool :
1571 pOut = _pVar->getAs<Bool>()->remove(_pArgs);
1574 case InternalType::ScilabPolynom :
1576 pOut = _pVar->getAs<Polynom>()->remove(_pArgs);
1579 case InternalType::ScilabInt8 :
1581 pOut = _pVar->getAs<Int8>()->remove(_pArgs);
1584 case InternalType::ScilabUInt8 :
1586 pOut = _pVar->getAs<UInt8>()->remove(_pArgs);
1589 case InternalType::ScilabInt16 :
1591 pOut = _pVar->getAs<Int16>()->remove(_pArgs);
1594 case InternalType::ScilabUInt16 :
1596 pOut = _pVar->getAs<UInt16>()->remove(_pArgs);
1599 case InternalType::ScilabInt32 :
1601 pOut = _pVar->getAs<Int32>()->remove(_pArgs);
1604 case InternalType::ScilabUInt32 :
1606 pOut = _pVar->getAs<UInt32>()->remove(_pArgs);
1609 case InternalType::ScilabInt64 :
1611 pOut = _pVar->getAs<Int64>()->remove(_pArgs);
1614 case InternalType::ScilabUInt64 :
1616 pOut = _pVar->getAs<UInt64>()->remove(_pArgs);
1619 case InternalType::ScilabSparse :
1621 pOut = _pVar->getAs<Sparse>()->remove(_pArgs);
1624 case InternalType::ScilabSparseBool :
1626 pOut = _pVar->getAs<SparseBool>()->remove(_pArgs);
1629 case InternalType::ScilabStruct :
1631 pOut = _pVar->getAs<Struct>()->insert(_pArgs, _pInsert);
1634 case InternalType::ScilabHandle :
1636 types::GraphicHandle* pH = _pVar->getAs<GraphicHandle>();
1637 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1642 ast::ExecVisitor exec;
1646 in.push_back(_pInsert);
1648 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1649 Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
1650 if (ret == Callable::OK)
1659 pOut = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1664 else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<Double>()->getSize() == 0))
1666 //insert in a new variable or []
1667 //call static insert function
1668 //if _pVar == NULL and pArg is single string, it's a struct creation
1669 if ((*_pArgs)[0]->isString())
1671 String *pS = (*_pArgs)[0]->getAs<types::String>();
1672 Struct* pStr = new Struct(1, 1);
1674 if (_pArgs->size() != 1 || pS->isScalar() == false)
1681 std::wostringstream os;
1682 os << _W("Invalid Index.\n");
1683 throw ast::ScilabError(os.str(), 999, e.getLocation());
1686 pStr->addField(pS->get(0));
1687 pStr->get(0)->set(pS->get(0), _pInsert);
1692 switch (_pInsert->getType())
1694 case InternalType::ScilabDouble :
1695 pOut = Double::insertNew(_pArgs, _pInsert);
1697 case InternalType::ScilabString :
1698 pOut = String::insertNew(_pArgs, _pInsert);
1700 case InternalType::ScilabCell :
1701 pOut = Cell::insertNew(_pArgs, _pInsert);
1703 case InternalType::ScilabBool :
1704 pOut = Bool::insertNew(_pArgs, _pInsert);
1706 case InternalType::ScilabPolynom :
1707 pOut = Polynom::insertNew(_pArgs, _pInsert);
1709 case InternalType::ScilabInt8 :
1710 pOut = Int8::insertNew(_pArgs, _pInsert);
1712 case InternalType::ScilabUInt8 :
1713 pOut = UInt8::insertNew(_pArgs, _pInsert);
1715 case InternalType::ScilabInt16 :
1716 pOut = Int16::insertNew(_pArgs, _pInsert);
1718 case InternalType::ScilabUInt16 :
1719 pOut = UInt16::insertNew(_pArgs, _pInsert);
1721 case InternalType::ScilabInt32 :
1722 pOut = Int32::insertNew(_pArgs, _pInsert);
1724 case InternalType::ScilabUInt32 :
1725 pOut = UInt32::insertNew(_pArgs, _pInsert);
1727 case InternalType::ScilabInt64 :
1728 pOut = Int64::insertNew(_pArgs, _pInsert);
1730 case InternalType::ScilabUInt64 :
1731 pOut = UInt64::insertNew(_pArgs, _pInsert);
1733 case InternalType::ScilabSparse :
1734 pOut = Sparse::insertNew(_pArgs, _pInsert);
1736 case InternalType::ScilabSparseBool :
1737 pOut = SparseBool::insertNew(_pArgs, _pInsert);
1739 case InternalType::ScilabHandle:
1740 pOut = GraphicHandle::insertNew(_pArgs, _pInsert);
1745 types::Double* pEmpty = types::Double::Empty();
1746 pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1755 //call type insert function
1756 InternalType* pRet = NULL;
1758 //check types compatibilties
1759 if (_pVar->isDouble() && _pInsert->isDouble())
1761 pRet = _pVar->getAs<Double>()->insert(_pArgs, _pInsert);
1763 else if (_pVar->isDouble() && _pInsert->isSparse())
1765 Sparse* pSp = _pInsert->getAs<Sparse>();
1766 Double* pD = new Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1768 pRet = _pVar->getAs<Double>()->insert(_pArgs, pD);
1771 else if (_pVar->isString() && _pInsert->isString())
1773 pRet = _pVar->getAs<String>()->insert(_pArgs, _pInsert);
1775 else if (_pVar->isCell() && _pInsert->isCell())
1777 pRet = _pVar->getAs<Cell>()->insert(_pArgs, _pInsert);
1779 else if (_pVar->isBool() && _pInsert->isBool())
1781 pRet = _pVar->getAs<Bool>()->insert(_pArgs, _pInsert);
1783 else if (_pVar->isSparse() && _pInsert->isSparse())
1785 pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert->getAs<Sparse>());
1787 else if (_pVar->isSparse() && _pInsert->isDouble())
1789 pRet = _pVar->getAs<Sparse>()->insert(_pArgs, _pInsert);
1791 else if (_pVar->isSparseBool() && _pInsert->isSparseBool())
1793 pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert->getAs<SparseBool>());
1795 else if (_pVar->isSparseBool() && _pInsert->isBool())
1797 pRet = _pVar->getAs<SparseBool>()->insert(_pArgs, _pInsert);
1799 else if (_pVar->isDouble() && _pInsert->isPoly())
1801 Double* pDest = _pVar->getAs<Double>();
1802 Polynom* pIns = _pInsert->getAs<Polynom>();
1803 int iSize = pDest->getSize();
1804 int* piRanks = new int[iSize];
1805 memset(piRanks, 0x00, iSize * sizeof(int));
1806 Polynom* pP = new Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1808 pP->setComplex(pDest->isComplex());
1810 if (pP->isComplex())
1812 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1814 double dblR = pDest->get(idx);
1815 double dblI = pDest->getImg(idx);
1816 pP->get(idx)->setCoef(&dblR, &dblI);
1821 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1823 double dblR = pDest->get(idx);
1824 pP->get(idx)->setCoef(&dblR, NULL);
1828 pRet = pP->insert(_pArgs, pIns);
1829 pDest->DecreaseRef();
1831 else if (_pVar->isPoly() && _pInsert->isDouble())
1833 Polynom* pDest = _pVar->getAs<Polynom>();
1834 Double* pIns = _pInsert->getAs<Double>();
1835 bool isComplexIns = pIns->isComplex();
1836 int iSize = pIns->getSize();
1837 int* piRanks = new int[iSize];
1838 memset(piRanks, 0x00, iSize * sizeof(int));
1840 //create a new polynom with Double to insert it into dest polynom
1841 Polynom* pP = new Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
1846 double* pR = pIns->get();
1847 double* pI = pIns->getImg();
1848 SinglePoly** pSP = pP->get();
1849 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1851 double dblR = pR[idx];
1852 double dblI = pI[idx];
1853 pSP[idx]->setComplex(true);
1854 pSP[idx]->setCoef(&dblR, &dblI);
1859 double* pdblR = pIns->get();
1860 SinglePoly** pSP = pP->get();
1861 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1863 double dblR = pdblR[idx];
1864 pSP[idx]->setCoef(&dblR, NULL);
1868 pRet = pDest->insert(_pArgs, pP);
1871 else if (_pVar->isPoly() && _pInsert->isPoly())
1873 pRet = _pVar->getAs<Polynom>()->insert(_pArgs, _pInsert);
1875 else if (_pVar->isInt8() && _pInsert->isInt8())
1877 pRet = _pVar->getAs<Int8>()->insert(_pArgs, _pInsert);
1879 else if (_pVar->isUInt8() && _pInsert->isUInt8())
1881 pRet = _pVar->getAs<UInt8>()->insert(_pArgs, _pInsert);
1883 else if (_pVar->isInt16() && _pInsert->isInt16())
1885 pRet = _pVar->getAs<Int16>()->insert(_pArgs, _pInsert);
1887 else if (_pVar->isUInt16() && _pInsert->isUInt16())
1889 pRet = _pVar->getAs<UInt16>()->insert(_pArgs, _pInsert);
1891 else if (_pVar->isInt32() && _pInsert->isInt32())
1893 pRet = _pVar->getAs<Int32>()->insert(_pArgs, _pInsert);
1895 else if (_pVar->isUInt32() && _pInsert->isUInt32())
1897 pRet = _pVar->getAs<UInt32>()->insert(_pArgs, _pInsert);
1899 else if (_pVar->isInt64() && _pInsert->isInt64())
1901 pRet = _pVar->getAs<Int64>()->insert(_pArgs, _pInsert);
1903 else if (_pVar->isUInt64() && _pInsert->isUInt64())
1905 pRet = _pVar->getAs<UInt64>()->insert(_pArgs, _pInsert);
1907 else if (_pVar->isStruct())
1909 Struct* pStruct = _pVar->getAs<Struct>();
1910 // insert something in a field of a struct
1911 if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
1914 String *pS = (*_pArgs)[0]->getAs<types::String>();
1915 if (pS->isScalar() == false)
1922 std::wostringstream os;
1923 os << _W("Invalid Index.\n");
1924 throw ast::ScilabError(os.str(), 999, e.getLocation());
1927 pStruct->addField(pS->get(0));
1928 for (int i = 0; i < pStruct->getSize(); i++)
1930 pStruct->get(i)->set(pS->get(0), _pInsert);
1935 else // insert something in a struct
1937 if (_pInsert->isStruct())
1939 String* pStrFieldsName = pStruct->getFieldNames();
1940 Struct* pStructInsert = _pInsert->clone()->getAs<Struct>();
1941 String* pStrInsertFieldsName = pStructInsert->getFieldNames();
1942 Struct* pStructRet = NULL;
1944 // if not an empty struct
1947 // insert fields of pStruct in pStructInsert
1948 for (int i = pStrFieldsName->getSize(); i > 0; i--)
1950 if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
1952 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
1956 std::wstring pwcsField = pStrFieldsName->get(i - 1);
1957 List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
1959 for (int i = 0; i < pLExtract->getSize(); i++)
1961 // protect element wich are not cloned before call removeField.
1962 pLExtract->get(i)->IncreaseRef();
1965 pStructInsert->removeField(pwcsField);
1966 pStructInsert->addFieldFront(pwcsField);
1968 for (int i = 0; i < pLExtract->getSize(); i++)
1970 // set elements in the new position
1971 pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
1974 pLExtract->killMe();
1978 pStrFieldsName->killMe();
1981 // insert elements in following pArgs
1982 pRet = pStruct->insert(_pArgs, pStructInsert);
1983 pStructRet = pRet->getAs<Struct>();
1985 pStructInsert->killMe();
1987 // insert fields of pStructInsert in pRet
1988 for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
1990 if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
1992 pStructRet->addField(pStrInsertFieldsName->get(i));
1996 pStrInsertFieldsName->killMe();
2000 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2004 else if (_pVar->isTList() || _pVar->isMList())
2006 TList* pTL = _pVar->getAs<TList>();
2007 if (_pArgs->size() == 1)
2009 if ((*_pArgs)[0]->isString())
2012 String *pS = (*_pArgs)[0]->getAs<types::String>();
2013 if (pS->isScalar() == false)
2021 std::wostringstream os;
2022 os << _W("Invalid Index.\n");
2023 throw ast::ScilabError(os.str(), 999, e.getLocation());
2026 if (_pInsert->isListDelete())
2028 return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2031 if (pTL->exists(pS->get(0)))
2033 pTL->set(pS->get(0), _pInsert);
2038 return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2041 //types::typed_list in;
2042 //types::typed_list out;
2043 //std::wstring function_name = L"%l_e";
2045 //_pInsert->IncreaseRef();
2046 //in.push_back(_pInsert);
2048 //Overload::call(function_name, in, 1, out, &exec);
2049 //_pInsert->DecreaseRef();
2051 //if (out.size() != 0)
2060 if (_pVar->isMList())
2062 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2066 pRet = pTL->insert(_pArgs, _pInsert);
2072 if (_pVar->isMList())
2074 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2078 // call the overload if it exists.
2079 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2082 // else normal insert
2083 pRet = pTL->insert(_pArgs, _pInsert);
2088 else if (_pVar->isList())
2090 pRet = _pVar->getAs<List>()->insert(_pArgs, _pInsert);
2094 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2097 else if (_pVar->isHandle())
2099 if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2102 types::GraphicHandle* pH = _pVar->getAs<types::GraphicHandle>();
2103 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
2107 ast::ExecVisitor exec;
2111 in.push_back(_pInsert);
2113 Function* pCall = (Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2116 Callable::ReturnValue ret = pCall->call(in, opt, 1, out, &exec);
2117 if (ret == Callable::OK)
2125 pRet = _pVar->getAs<types::GraphicHandle>()->insert(_pArgs, _pInsert);
2128 else if (_pVar->isUserType())
2130 pRet = _pVar->getAs<types::UserType>()->insert(_pArgs, _pInsert);
2133 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2139 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2153 void callOnPrompt(void)
2155 static symbol::Variable* onPrompt = NULL;
2157 if (onPrompt == NULL)
2159 onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2162 types::InternalType* pOnPrompt = NULL;
2163 pOnPrompt = onPrompt->get();
2164 if (pOnPrompt != NULL && pOnPrompt->isCallable())
2166 types::typed_list in;
2167 types::typed_list out;
2168 types::optional_list opt;
2169 ast::ExecVisitor execCall;
2170 pOnPrompt->getAs<types::Callable>()->call(in, opt, 1, out, &execCall);
2174 List* getPropertyTree(ast::Exp* e, List* pList)
2178 ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(e);
2181 pList->append(new String(pVar->getSymbol().getName().c_str()));
2186 ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(e);
2189 pList = getPropertyTree(&pCall->getName(), pList);
2190 ast::ExecVisitor exec;
2191 ast::exps_t l = pCall->getArgs();
2192 ast::exps_t::const_iterator it;
2193 for (ast::exps_t::const_iterator it = l.begin(), itEnd = l.end() ; it != itEnd ; ++it)
2197 (*it)->accept(exec);
2198 pList->append(exec.getResult());
2201 catch (ast::ScilabException e)
2211 ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(e);
2214 pList = getPropertyTree(pField->getHead(), pList);
2215 pList = getPropertyTree(pField->getTail(), pList);
2222 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2224 ast::Exp* newTree = NULL;
2225 unsigned char *newast = NULL;
2226 ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2227 ast::DeserializeVisitor* d = NULL;
2231 unsigned char* astbin = s->serialize();
2232 //call ocamlpro typer
2233 //char *newast = ocamlpro_typer(astbin);
2239 d = new ast::DeserializeVisitor(newast);
2240 newTree = d->deserialize();
2244 std::wstring msgS(_msg + L" serialize");
2245 std::wstring msgD(_msg + L" deserialize");
2249 unsigned char* astbin = s->serialize();
2250 timer.check(msgS.c_str());
2252 //call ocamlpro typer
2253 //char *newast = ocamlpro_typer(astbin);
2260 d = new ast::DeserializeVisitor(newast);
2261 newTree = d->deserialize();
2262 timer.check(msgD.c_str());