2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
20 #include "visitor_common.hxx"
22 #include "fieldexp.hxx"
23 #include "simplevar.hxx"
24 #include "callexp.hxx"
26 #include "context.hxx"
27 #include "execvisitor.hxx"
28 #include "serializervisitor.hxx"
29 #include "deserializervisitor.hxx"
30 #include "localization.hxx"
33 #include "alltypes.hxx"
37 #include "storeCommand.h"
40 size_t ast::Ast::globalNodeNumber = 0;
43 * Generate destination variable from _poSource type and size parameters
45 types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _iCols)
47 types::InternalType* poResult = NULL;
48 switch (_poSource->getType())
50 case types::InternalType::ScilabDouble :
51 poResult = new types::Double(_iRows, _iCols, false);
53 case types::InternalType::ScilabBool :
54 poResult = new types::Bool(_iRows, _iCols);
56 case types::InternalType::ScilabInt8 :
57 poResult = new types::Int8(_iRows, _iCols);
59 case types::InternalType::ScilabUInt8 :
60 poResult = new types::UInt8(_iRows, _iCols);
62 case types::InternalType::ScilabInt16 :
63 poResult = new types::Int16(_iRows, _iCols);
65 case types::InternalType::ScilabUInt16 :
66 poResult = new types::UInt16(_iRows, _iCols);
68 case types::InternalType::ScilabInt32 :
69 poResult = new types::Int32(_iRows, _iCols);
71 case types::InternalType::ScilabUInt32 :
72 poResult = new types::UInt32(_iRows, _iCols);
74 case types::InternalType::ScilabInt64 :
75 poResult = new types::Int64(_iRows, _iCols);
77 case types::InternalType::ScilabUInt64 :
78 poResult = new types::UInt64(_iRows, _iCols);
80 case types::InternalType::ScilabString :
81 poResult = new types::String(_iRows, _iCols);
83 case types::InternalType::ScilabPolynom :
85 int* piRank = new int[_iRows * _iCols];
86 memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
87 poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
91 case types::InternalType::ScilabImplicitList:
92 poResult = new types::ImplicitList();
95 // FIXME : What should we do here ??
101 types::InternalType* AddElementToVariableFromCol(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piCols)
103 types::InternalType *poResult = NULL;
104 types::InternalType::ScilabType TypeSource = _poSource->getType();
105 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
109 //First call, alloc _poSource
110 poResult = allocDest(_poSource, _iRows, _iCols);
111 TypeDest = TypeSource;
115 TypeDest = _poDest->getType();
119 if (TypeDest != TypeSource)
121 //check if source type is compatible with dest type
127 case types::InternalType::ScilabDouble :
128 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
130 poResult->getAs<types::Double>()->setComplex(true);
133 poResult->getAs<types::Double>()->fillFromCol(*_piCols, _poSource->getAs<types::Double>());
134 *_piCols += _poSource->getAs<types::Double>()->getCols();
145 types::InternalType* AddElementToVariableFromRow(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols, int *_piRows)
147 types::InternalType *poResult = NULL;
148 types::InternalType::ScilabType TypeSource = _poSource->getType();
149 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
153 //First call, alloc _poSource
154 poResult = allocDest(_poSource, _iRows, _iCols);
155 TypeDest = TypeSource;
159 TypeDest = _poDest->getType();
164 if (TypeDest != TypeSource)
166 //check if source type is compatible with dest type
172 case types::InternalType::ScilabDouble :
173 if (poResult->getAs<types::Double>()->isComplex() == false && _poSource->getAs<types::Double>()->isComplex() == true)
175 poResult->getAs<types::Double>()->setComplex(true);
178 poResult->getAs<types::Double>()->fillFromRow(*_piRows, _poSource->getAs<types::Double>());
179 *_piRows += _poSource->getAs<types::Double>()->getRows();
192 _iRows : Position if _poDest allready initialized else size of the matrix
193 _iCols : Position if _poDest allready initialized else size of the matrix
195 types::InternalType* AddElementToVariable(types::InternalType* _poDest, types::InternalType* _poSource, int _iRows, int _iCols)
197 types::InternalType *poResult = NULL;
199 types::InternalType::ScilabType TypeSource = _poSource->getType();
200 types::InternalType::ScilabType TypeDest = types::InternalType::ScilabInternal;
201 int iCurRow = _iRows;
202 int iCurCol = _iCols;
208 case types::InternalType::ScilabDouble :
209 poResult = new types::Double(_iRows, _iCols);
211 case types::InternalType::ScilabBool :
212 poResult = new types::Bool(_iRows, _iCols);
214 case types::InternalType::ScilabInt8 :
215 poResult = new types::Int8(_iRows, _iCols);
217 case types::InternalType::ScilabUInt8 :
218 poResult = new types::UInt8(_iRows, _iCols);
220 case types::InternalType::ScilabInt16 :
221 poResult = new types::Int16(_iRows, _iCols);
223 case types::InternalType::ScilabUInt16 :
224 poResult = new types::UInt16(_iRows, _iCols);
226 case types::InternalType::ScilabInt32 :
227 poResult = new types::Int32(_iRows, _iCols);
229 case types::InternalType::ScilabUInt32 :
230 poResult = new types::UInt32(_iRows, _iCols);
232 case types::InternalType::ScilabInt64 :
233 poResult = new types::Int64(_iRows, _iCols);
235 case types::InternalType::ScilabUInt64 :
236 poResult = new types::UInt64(_iRows, _iCols);
238 case types::InternalType::ScilabString :
239 poResult = new types::String(_iRows, _iCols);
241 case types::InternalType::ScilabSparse :
242 poResult = new types::Sparse(_iRows, _iCols);
244 case types::InternalType::ScilabSparseBool :
245 poResult = new types::SparseBool(_iRows, _iCols);
247 case types::InternalType::ScilabPolynom :
249 int* piRank = new int[_iRows * _iCols];
250 memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
251 poResult = new types::Polynom(_poSource->getAs<types::Polynom>()->getVariableName(), _iRows, _iCols, piRank);
255 case types::InternalType::ScilabImplicitList :
256 poResult = new types::ImplicitList();
258 case types::InternalType::ScilabHandle :
259 poResult = new types::GraphicHandle(_iRows, _iCols);
262 // FIXME What should we do here ...
267 TypeDest = TypeSource;
271 TypeDest = _poDest->getType();
277 if (TypeDest != TypeSource)
279 //check if source type is compatible with dest type
282 case types::InternalType::ScilabDouble :
283 if (TypeSource == types::InternalType::ScilabPolynom)
285 types::Double *poDest = _poDest->getAs<types::Double>();
286 types::Polynom* pPSource = _poSource->getAs<types::Polynom>();
288 //Convert Dest to ScilabPolynom
289 int iSize = poDest->getSize();
290 int *piRank = new int[iSize];
291 memset(piRank, 0x00, iSize * sizeof(int));
292 if (isNew && poResult)
296 poResult = new types::Polynom(pPSource->getVariableName(), poDest->getRows(), poDest->getCols(), piRank);
299 types::Polynom* pPResult = poResult->getAs<types::Polynom>();
300 pPResult->setComplex(poDest->isComplex());
302 double *pR = poDest->getReal();
303 types::SinglePoly** pSP = pPResult->get();
305 if (poDest->isComplex())
307 double *pI = poDest->getImg();
308 for (int i = 0 ; i < iSize; i++)
310 pSP[i]->set(0, pR[i]);
311 pSP[i]->setImg(0, pI[i]);
316 for (int i = 0 ; i < iSize; i++)
318 pSP[i]->set(0, pR[i]);
322 for (int i = 0 ; i < pPSource->getRows() ; i++)
324 for (int j = 0 ; j < pPSource->getCols() ; j++)
326 pPResult->set(iCurRow + i, iCurCol + j, pPSource->get(i, j));
333 case types::InternalType::ScilabPolynom :
334 if (TypeSource == types::InternalType::ScilabDouble)
336 //Add Source like coef of the new element
337 types::Double* pD = _poSource->getAs<types::Double>();
338 types::Polynom* pPolyOut = poResult->getAs<types::Polynom>();
342 pPolyOut->setComplex(true);
343 for (int i = 0 ; i < pD->getRows() ; i++)
345 for (int j = 0 ; j < pD->getCols() ; j++)
347 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
350 double pDblR = pD->get(i, j);
351 double pDblI = pD->getImg(i, j);
352 pSPOut->setCoef(&pDblR, &pDblI);
358 for (int i = 0 ; i < pD->getRows() ; i++)
360 for (int j = 0 ; j < pD->getCols() ; j++)
362 types::SinglePoly* pSPOut = pPolyOut->get(iCurRow + i, iCurCol + j);
365 double pDbl = pD->get(i, j);
366 pSPOut->setCoef(&pDbl, NULL);
374 case types::InternalType::ScilabSparse :
375 if (TypeSource == types::InternalType::ScilabDouble)
377 types::Double* poSource = _poSource->getAs<types::Double>();
378 types::Sparse* spResult = poResult->getAs<types::Sparse>();
380 // Set complex the result if one of inputs is complex
381 if (poSource->isComplex())
383 if (spResult->isComplex() == false)
385 spResult->toComplex();
389 // Add poSource at the end of spResult
390 if (spResult->isComplex())
392 if (poSource->isComplex())
394 for (int i = 0; i < poSource->getRows(); i++)
396 for (int j = 0; j < poSource->getCols(); j++)
398 double dbl = poSource->get(i, j);
399 double dblImg = poSource->getImg(i, j);
400 if (dbl != 0 || dblImg != 0)
402 spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, dblImg));
409 for (int i = 0; i < poSource->getRows(); i++)
411 for (int j = 0; j < poSource->getCols(); j++)
413 double dbl = poSource->get(i, j);
416 spResult->set(i + iCurRow, j + iCurCol, std::complex<double>(dbl, 0));
424 for (int i = 0; i < poSource->getRows(); i++)
426 for (int j = 0; j < poSource->getCols(); j++)
428 double dbl = poSource->get(i, j);
431 spResult->set(i + iCurRow, j + iCurCol, dbl);
440 case types::InternalType::ScilabSparseBool :
441 if (TypeSource == types::InternalType::ScilabBool)
443 types::Bool* poSource = _poSource->getAs<types::Bool>();
444 types::SparseBool* spResult = poResult->getAs<types::SparseBool>();
446 // Add poSource at the end of spResult
447 for (int i = 0; i < poSource->getRows(); i++)
449 for (int j = 0; j < poSource->getCols(); j++)
451 bool bValue = poSource->get(i, j) != 0;
454 spResult->set(i + iCurRow, j + iCurCol, true);
470 //Just add the new value in the current item
473 case types::InternalType::ScilabDouble :
474 poResult->getAs<types::Double>()->append(iCurRow, iCurCol, _poSource);
476 case types::InternalType::ScilabPolynom :
477 poResult->getAs<types::Polynom>()->append(iCurRow, iCurCol, _poSource);
479 case types::InternalType::ScilabBool:
480 poResult->getAs<types::Bool>()->append(iCurRow, iCurCol, _poSource);
482 case types::InternalType::ScilabInt8 :
483 poResult->getAs<types::Int8>()->append(iCurRow, iCurCol, _poSource);
485 case types::InternalType::ScilabUInt8 :
486 poResult->getAs<types::UInt8>()->append(iCurRow, iCurCol, _poSource);
488 case types::InternalType::ScilabInt16 :
489 poResult->getAs<types::Int16>()->append(iCurRow, iCurCol, _poSource);
491 case types::InternalType::ScilabUInt16 :
492 poResult->getAs<types::UInt16>()->append(iCurRow, iCurCol, _poSource);
494 case types::InternalType::ScilabInt32 :
495 poResult->getAs<types::Int32>()->append(iCurRow, iCurCol, _poSource);
497 case types::InternalType::ScilabUInt32 :
498 poResult->getAs<types::UInt32>()->append(iCurRow, iCurCol, _poSource);
500 case types::InternalType::ScilabInt64 :
501 poResult->getAs<types::Int64>()->append(iCurRow, iCurCol, _poSource);
503 case types::InternalType::ScilabUInt64 :
504 poResult->getAs<types::UInt64>()->append(iCurRow, iCurCol, _poSource);
506 case types::InternalType::ScilabSparse :
507 poResult->getAs<types::Sparse>()->append(iCurRow, iCurCol, _poSource->getAs<types::Sparse>());
509 case types::InternalType::ScilabSparseBool :
510 poResult->getAs<types::SparseBool>()->append(iCurRow, iCurCol, _poSource->getAs<types::SparseBool>());
512 case types::InternalType::ScilabString :
514 poResult->getAs<types::String>()->append(iCurRow, iCurCol, _poSource);
517 case types::InternalType::ScilabImplicitList :
519 types::ImplicitList* pIL = _poSource->getAs<types::ImplicitList>();
520 types::ImplicitList* pOL = poResult->getAs<types::ImplicitList>();
521 pOL->setStart(pIL->getStart());
522 pOL->setStep(pIL->getStep());
523 pOL->setEnd(pIL->getEnd());
526 case types::InternalType::ScilabHandle :
527 poResult->getAs<types::GraphicHandle>()->append(iCurRow, iCurCol, _poSource);
537 const std::wstring* getStructNameFromExp(const ast::Exp* _pExp)
539 const ast::FieldExp* pField = dynamic_cast<const ast::FieldExp*>(_pExp);
540 const ast::SimpleVar* pVar = dynamic_cast<const ast::SimpleVar*>(_pExp);
541 const ast::CallExp* pCall = dynamic_cast<const ast::CallExp*>(_pExp);
545 return getStructNameFromExp(pField->getHead());
549 return &(pVar->getSymbol().getName());
553 return getStructNameFromExp(&(pCall->getName()));
557 std::wostringstream os;
558 os << _W("Unknown expression");
559 //os << ((Location)e.getRightExp().getLocation()).getLocationString() << std::endl;
560 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
565 /*** overload insertion || extraction ***/
566 //%x_i_x(i1, i2, ..., in, source, dest) || %x_e(i1, i2, ..., in, source, dest)
567 //i1, ..., in : indexes
568 //dest : variable where insert data || NULL
569 //source : data to insert || extract indexes from source
570 types::InternalType* callOverload(const ast::Exp& e, const std::wstring& _strType, types::typed_list* _pArgs, types::InternalType* _source, types::InternalType* _dest)
572 types::Function::ReturnValue ret = types::Function::Error;
573 types::InternalType* pITOut = NULL;
574 types::typed_list in;
575 types::typed_list out;
577 std::wstring function_name;
578 function_name = L"%" + _source->getShortTypeStr() + L"_" + _strType;
580 for (int i = 0; i < (int)_pArgs->size(); i++)
582 (*_pArgs)[i]->IncreaseRef();
583 in.push_back((*_pArgs)[i]);
586 _source->IncreaseRef();
587 in.push_back(_source);
591 _dest->IncreaseRef();
594 function_name += L"_" + _dest->getShortTypeStr();
597 types::InternalType* pFunc = symbol::Context::getInstance()->get(symbol::Symbol(function_name));
598 // if %type_6 doesn't exist, call %l_6
599 if (_dest == NULL && pFunc == NULL)
601 function_name = L"%l_" + _strType;
604 // For insertion in TList, call normal insertion if overload doesn't exits
605 if ((_dest && _dest->isTList() && pFunc == NULL) == false || _source->isListDelete())
609 ret = Overload::call(function_name, in, 1, out);
611 catch (const ast::InternalError& error)
613 // unprotect variables
614 for (int i = 0; i < (int)_pArgs->size(); i++)
616 (*_pArgs)[i]->DecreaseRef();
619 _source->DecreaseRef();
622 _dest->DecreaseRef();
628 // unprotect variables
629 for (int i = 0; i < (int)_pArgs->size(); i++)
631 (*_pArgs)[i]->DecreaseRef();
634 _source->DecreaseRef();
637 _dest->DecreaseRef();
640 if (ret == types::Function::Error)
643 std::wostringstream os;
644 os << _W("Error in overload function: ") << function_name << std::endl;
645 throw ast::InternalError(os.str(), 999, e.getLocation());
653 else if (out.size() > 1)
655 types::List* pListOut = new types::List();
656 for (int i = 0; i < (int)out.size(); i++)
658 pListOut->append(out[i]);
668 bool getFieldsFromExp(ast::Exp* _pExp, std::list<ExpHistory*>& fields)
670 ast::FieldExp* pField = dynamic_cast<ast::FieldExp*>(_pExp);
671 ast::SimpleVar* pVar = dynamic_cast<ast::SimpleVar*>(_pExp);
672 ast::CallExp* pCall = dynamic_cast<ast::CallExp*>(_pExp);
673 ast::CellCallExp* pCell = dynamic_cast<ast::CellCallExp*>(_pExp);
677 if (getFieldsFromExp(pField->getHead(), fields))
679 return getFieldsFromExp(pField->getTail(), fields);
688 fields.push_back(new ExpHistory(NULL, pVar));
692 ExpHistory * pEHParent = fields.back();
693 ExpHistory * pEH = new ExpHistory(pEHParent, pVar);
694 pEH->setLevel(pEHParent->getLevel() + 1);
695 fields.push_back(pEH);
702 bool bArgList = false;
703 types::List* pList = NULL;
707 ast::ExecVisitor execMe;
708 ast::exps_t args = pCall->getArgs();
709 types::typed_list* pCurrentArgs = execMe.GetArgumentList(args);
711 if (getFieldsFromExp(&pCall->getName(), fields) == false)
716 // used to manage insertion with list in argument
717 // a(list("field", 2)) = 2 as a.field(2)
718 if (pCurrentArgs && pCurrentArgs->size() > 0 &&
719 (*pCurrentArgs)[0]->isList() &&
720 (*pCurrentArgs)[0]->isTList() == false &&
721 (*pCurrentArgs)[0]->isMList() == false)
724 pList = (*pCurrentArgs)[0]->getAs<types::List>();
725 //pList->IncreaseRef();
726 pCurrentArgs->clear();
727 pCurrentArgs->push_back(pList->get(iListIncr));
728 iListSize = pList->getSize();
735 pCurrentArgs->size() == 1 &&
736 (*pCurrentArgs)[0]->isString() &&
737 (*pCurrentArgs)[0]->getAs<types::String>()->getSize() == 1)
739 // a("b") => a.b or a(x)("b") => a(x).b
740 ExpHistory * pEHParent = fields.back();
741 ast::SimpleVar* pFieldVar = new ast::SimpleVar(pCall->getLocation(), symbol::Symbol((*pCurrentArgs)[0]->getAs<types::String>()->get(0)));
742 ExpHistory * pEH = new ExpHistory(pEHParent, pFieldVar);
743 pEH->setLevel(pEHParent->getLevel() + 1);
744 pEH->setExpOwner(true);
746 (*pCurrentArgs)[0]->killMe();
750 fields.push_back(pEH);
752 else if (fields.back()->getArgs())
755 ExpHistory * pEHParent = fields.back();
756 ExpHistory * pEH = new ExpHistory(pEHParent, pCurrentArgs);
757 pEH->setLevel(pEHParent->getLevel() + 1);
758 pEH->setArgsOwner(true);
759 fields.push_back(pEH);
764 fields.back()->setArgs(pCurrentArgs);
765 fields.back()->setArgsOwner(true);
771 if (iListIncr < iListSize)
773 // create new args for next loop.
774 pCurrentArgs = new types::typed_list();
775 pCurrentArgs->push_back(pList->get(iListIncr)->clone());
779 while (iListIncr < iListSize);
789 fields.back()->setCellExp();
800 types::InternalType* evaluateFields(const ast::Exp* _pExp, std::list<ExpHistory*>& fields, types::InternalType* _pAssignValue)
802 std::list<ExpHistory*> evalFields;
803 std::list<ExpHistory*> workFields;
805 bool bPutInCtx = false;
806 types::InternalType* pITMain = NULL;
810 //*** get main variable ***//
811 std::list<ExpHistory*>::iterator iterFields = fields.begin();
812 ExpHistory* pFirstField = *iterFields;
813 symbol::Context* ctx = symbol::Context::getInstance();
815 if (ctx->isprotected(pFirstField->getExp()->getSymbol()))
817 std::wostringstream os;
818 os << _W("Redefining permanent variable.\n");
819 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
822 ast::SimpleVar* spMainExp = pFirstField->getExp();
823 pITMain = ctx->getCurrentLevel(spMainExp->getSymbol());
825 // looking for a callable
828 pITMain = ctx->get(spMainExp->getSymbol());
829 if (pITMain && pITMain->isCallable() == false)
837 if (pFirstField->isCellExp())
839 // a{x}, where "a" doesn't exists
840 pITMain = new types::Cell(1, 1);
841 pITMain->IncreaseRef();
844 else if (fields.size() > 1)
847 //"a" does not exist or it is another type, create it with size 1,1 and return it
848 //create new structure variable
849 pITMain = new types::Struct(1, 1);
850 pITMain->IncreaseRef();
855 // a(x) = "something" and a does not exist
856 // a will be create in insertionCall
858 else if (pITMain->getRef() > 1 && pITMain->isHandle() == false)
861 pITMain = pITMain->clone();
862 pITMain->IncreaseRef();
864 else if (pITMain == _pAssignValue)
866 // clone me before insert me in myself.
867 // ie : a.b = 2; a.b.c.d = a;
868 _pAssignValue = _pAssignValue->clone();
873 workFields.push_back(new ExpHistory(NULL,
874 pFirstField->getExp(),
875 pFirstField->getArgs(),
876 pFirstField->getLevel(),
877 pFirstField->isCellExp(),
880 //*** evaluate fields ***//
881 while (iterFields != fields.end())
883 ExpHistory* pEH = workFields.front();
884 evalFields.push_back(pEH);
885 workFields.pop_front();
887 types::InternalType* pITCurrent = pEH->getCurrent();
889 if (pEH->isCellExp() && pITCurrent->isCell() == false)
891 std::wostringstream os;
892 os << _W("Wrong insertion : use extraction with {} only on a Cell.");
893 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
896 if (pITCurrent->isStruct())
898 types::Struct* pStruct = pITCurrent->getAs<types::Struct>();
899 // In case where pStruct is in several scilab variable,
900 // we have to clone it for keep the other variables unchanged.
901 if (pStruct->getRef() > 1)
903 pStruct = pStruct->clone();
904 pEH->setCurrent(pStruct);
905 pEH->setReinsertion();
908 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
910 if (pEH->needResize())
912 if (pEH->getArgsDims() == 1)
914 std::wostringstream os;
915 os << _W("Invalid index.");
916 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
919 // resize current struct
920 pStruct = pStruct->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
921 pEH->setCurrent(pStruct);
924 // create field in parent if it not exist
925 if (pStruct->exists(pwcsFieldname) == false)
927 pStruct = pStruct->addField(pwcsFieldname);
928 pEH->setCurrent(pStruct);
933 types::InternalType* pIT = pStruct->extractWithoutClone(pEH->getArgs());
934 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pIT));
938 // check if the field x is the last field
939 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
941 if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
943 // create pArg with "x" and set it as argument of "a"
944 types::typed_list* args = new types::typed_list();
945 args->push_back(new types::String(pwcsFieldname.c_str()));
948 // a.x where x is the last field
949 // insert directly in x instead of extract then insert
950 ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
951 pEHNext->setReinsertion(true);
952 evalFields.push_back(pEHNext);
953 if (workFields.empty())
960 // Avoid insertion in most of one element.
961 if (pStruct->isScalar() == false)
963 std::wostringstream os;
964 os << _W("Unable to insert multiple item in a Struct.");
965 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
968 // extract field x and append it to elements for next recursion.
969 types::List* pLOut = pStruct->extractFieldWithoutClone(pwcsFieldname);
971 // pStruct must be scalar because we cant insert most of one element in the same insertion
972 types::InternalType* pIT = pLOut->get(0);
973 if (pIT->getRef() > 2) //One for my own ref + 1 for "extractFieldWithoutClone" artificial ref
975 // clone element before modify it.
976 //pIT->DecreaseRef();
978 pStruct->get(0)->set(pwcsFieldname, pIT);
981 ExpHistory* pEHChield = new ExpHistory(pEH,
982 (*iterFields)->getExp(),
983 (*iterFields)->getArgs(),
984 (*iterFields)->getLevel(),
985 (*iterFields)->isCellExp(),
988 pEHChield->setWhereReinsert(0);
989 workFields.push_back(pEHChield);
995 else if (pITCurrent->isTList() || pITCurrent->isMList())
997 types::TList* pTL = pITCurrent->getAs<types::TList>();
998 types::typed_list* pArgs = pEH->getArgs();
1001 if (pArgs->size() > 1 || pITCurrent->isMList())
1004 types::InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
1005 if ((*iterFields)->getExp() == NULL)
1008 // extract a(x) and push_BACK to extract y
1009 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1010 workFields.back()->setReinsertion();
1015 // extract a(x) and push_FRONT to extract b
1016 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1017 workFields.front()->setReinsertion();
1023 int iNewSize = pEH->getSizeFromArgs();
1024 if (pTL->getSize() < iNewSize)
1026 pTL = pTL->set(iNewSize - 1, new types::ListUndefined());
1027 pEH->setCurrent(pTL);
1030 // update pArgs variables with new argument computed in getSizeFromArgs
1031 pArgs = pEH->getArgs();
1033 types::InternalType* pIT = pTL->extract(pArgs);
1034 types::List* pList = pIT->getAs<types::List>();
1036 if (pList->getSize() > 1)
1039 std::wostringstream os;
1040 os << _W("Unable to insert multiple item in a List.");
1041 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1044 double* pdblArgs = (*pArgs)[0]->getAs<types::Double>()->get();
1045 if ((*iterFields)->getExp() == NULL)
1048 // extract a(x) and push_BACK to extract y
1049 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pList->get(0));
1050 pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
1051 workFields.push_back(pEHExtract);
1056 // extract a(x) and push_FRONT to extract b
1057 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pList->get(0));
1058 pEHExtract->setWhereReinsert((int)(pdblArgs[0] - 1));
1059 workFields.push_front(pEHExtract);
1062 //extract create a list to store items
1068 // get string "x" of a.x
1069 types::InternalType* pExtract = NULL;
1070 std::wstring pwcsFieldname = L"";
1071 bool bReinsert = false;
1072 ExpHistory* pEHChield = NULL;
1074 pwcsFieldname = (*iterFields)->getExpAsString();
1076 // check if the field x is the last field
1077 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1079 if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1081 // create pArg with "x" and set it as argument of "a"
1082 types::typed_list* args = new types::typed_list();
1083 args->push_back(new types::String(pwcsFieldname.c_str()));
1086 // a.x where x is the last field
1087 // insert directly in x instead of extract then insert
1088 ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1089 pEHNext->setReinsertion(true);
1090 evalFields.push_back(pEHNext);
1091 if (workFields.empty())
1098 // check if field exists
1099 if (pTL->exists(pwcsFieldname) == false)
1101 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1104 if (iterFieldsNext != fields.end() || (*iterFields)->getArgs() != NULL)
1106 // M=mlist(['MType','x','y'], ...
1107 // M.rows1 = "somthing"
1108 pArgs = new types::typed_list();
1109 pArgs->push_back(new types::String(pwcsFieldname.c_str()));
1112 pExtract = callOverload(*pEH->getExp(), L"6", pArgs, pTL, NULL);
1120 // extract field x and append it to elements for next recursion.
1121 pExtract = pTL->getField(pwcsFieldname);
1124 pEHChield = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract);
1125 workFields.push_back(pEHChield);
1129 pEHChield->setReinsertion();
1134 else if (pITCurrent->isList())
1136 types::List* pL = pITCurrent->getAs<types::List>();
1137 if (pEH->getParent() && pEH->getParent()->getLevel() == pEH->getLevel())
1139 std::wostringstream os;
1140 os << _W("Wrong insertion.");
1141 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1143 // // pITCurrent is an extraction of other Type
1144 // for (int iLoop = 0; iLoop < pL->getSize(); iLoop++)
1146 // ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get(iLoop));
1147 // pEHExtract->setWhereReinsert(iLoop);
1148 // workFields.push_front(pEHExtract);
1153 // pITCurrent is a field
1156 if (pEH->getArgs()->size() > 1)
1159 types::InternalType* pExtract = callOverload(*pEH->getExp(), L"6", pEH->getArgs(), pL, NULL);
1161 if ((*iterFields)->getExp() == NULL)
1164 // extract a(x) and push_BACK to extract next level
1165 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1166 workFields.back()->setReinsertion();
1171 // extract a(x) and push_FRONT to extract b from a(x)
1172 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1173 workFields.front()->setReinsertion();
1179 int iNewSize = pEH->getSizeFromArgs();
1180 if (pL->getSize() < iNewSize)
1182 pL = pL->set(iNewSize - 1, new types::ListUndefined());
1183 pEH->setCurrent(pL);
1186 types::Double* pDblArgs = (*pEH->getArgs())[0]->getAs<types::Double>();
1187 double* pdblArgs = pDblArgs->get();
1189 if ((*iterFields)->getExp() == NULL)
1191 // a(x)(y) => a.b(y)
1192 // extract a(x) and push_BACK to extract next level
1193 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1195 ExpHistory* pEHExtract = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1196 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1197 workFields.push_back(pEHExtract);
1203 // extract a(x) and push_FRONT to extract b from a(x)
1204 for (int iLoop = 0; iLoop < pDblArgs->getSize(); iLoop++)
1206 ExpHistory* pEHExtract = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pL->get((int)pdblArgs[iLoop] - 1));
1207 pEHExtract->setWhereReinsert((int)(pdblArgs[iLoop] - 1));
1208 workFields.push_front(pEHExtract);
1215 // a.x, get string "x"
1216 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1218 // create pArg with "x"
1219 types::typed_list* args = new types::typed_list();
1220 args->push_back(new types::String(pwcsFieldname.c_str()));
1223 // check if the field x is the last field
1224 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1226 if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1228 // a.x where x is the last field
1229 // insert directly in x instead of extract then insert
1230 ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1231 pEHNext->setReinsertion(true);
1232 evalFields.push_back(pEHNext);
1233 if (workFields.empty())
1241 types::InternalType* pExtract = callOverload(*pEH->getExp(), L"6", args, pL, NULL);
1243 // append extraction of a.x for next level.
1244 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1245 workFields.back()->setReinsertion();
1250 else if (pITCurrent->isHandle())
1252 types::typed_list* pArgs = pEH->getArgs();
1253 types::GraphicHandle* pGH = pITCurrent->getAs<types::GraphicHandle>();
1256 types::InternalType* pExtract = NULL;
1258 if (pArgs->size() == 1 && (*pArgs)[0]->isImplicitList() == false)
1261 pExtract = callOverload(*pEH->getExp(), L"e", pArgs, pITCurrent, NULL);
1265 pExtract = pGH->extract(pArgs);
1268 if (pExtract == NULL)
1270 std::wostringstream os;
1271 os << _W("Invalid index.");
1272 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1275 if ((*iterFields)->getExp() == NULL)
1278 // extract a(x) and push_BACK to extract next level
1279 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1280 workFields.back()->setReinsertion();
1285 // extract a(x) and push_FRONT to extract b from a(x)
1286 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1287 workFields.front()->setReinsertion();
1292 // a.x, get string "x"
1293 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1295 // create arg with next field
1296 types::typed_list* args = new types::typed_list();
1297 args->push_back(new types::String(pwcsFieldname.c_str()));
1300 // check if the field x is the last field
1301 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1303 if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1305 // a.x where x is the last field
1306 // insert directly in x instead of extract then insert
1307 ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1308 pEHNext->setReinsertion(true);
1309 evalFields.push_back(pEHNext);
1310 if (workFields.empty())
1318 types::InternalType* pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1320 // append extraction of a.x for next level.
1321 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1322 workFields.front()->setReinsertion();
1326 else if (pITCurrent->isCell())
1328 if (pEH->getArgs() && (*pEH->getArgs())[0]->isString() == false)
1330 if (pEH->isCellExp())
1332 types::Cell* pCell = pITCurrent->getAs<types::Cell>();
1333 // a{x} => extract like a(x){[1 2 ...]}
1334 if (pEH->getParent() && pEH->getLevel() == pEH->getParent()->getLevel())
1336 // extract each elements of a(x)
1337 for (int iCell = 0; iCell < pCell->getSize(); iCell++)
1339 types::InternalType* pIT = pCell->get(iCell);
1340 if ((*iterFields)->getExp() == NULL)
1343 ExpHistory* pEHChield = new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT);
1344 pEHChield->setWhereReinsert(iCell);
1345 workFields.push_back(pEHChield);
1350 ExpHistory* pEHChield = new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), false, pIT);
1351 pEHChield->setWhereReinsert(iCell);
1352 workFields.push_front(pEHChield);
1358 types::GenericType* pCell = pITCurrent->getAs<types::GenericType>();
1359 if (pEH->needResize())
1361 if (pEH->getArgsDims() == 1)
1363 std::wostringstream os;
1364 os << _W("Invalid index.");
1365 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1368 // resize current Cell
1369 pCell = pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims());
1370 pEH->setCurrent(pCell);
1373 types::InternalType* pIT = pCell->extract(pEH->getArgs());
1374 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), pEH->getArgs(), pEH->getLevel(), pEH->isCellExp(), pIT));
1375 workFields.front()->setReinsertion();
1380 if ((*iterFields)->isCellExp())
1382 types::GenericType* pCell = pITCurrent->getAs<types::GenericType>();
1385 if (pEH->needResize())
1387 if (pEH->getArgsDims() == 1)
1389 std::wostringstream os;
1390 os << _W("Invalid index.");
1391 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1394 // resize current Cell
1395 pCell = pCell->resize(pEH->getArgsDimsArray(), pEH->getArgsDims())->getAs<types::Cell>();
1396 pEH->setCurrent(pCell);
1399 types::InternalType* pIT = pCell->extract(pEH->getArgs());
1400 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pIT));
1401 workFields.front()->setReinsertion();
1406 std::wostringstream os;
1407 os << _W("Wrong insertion in a Cell.");
1408 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1414 std::wostringstream os;
1415 os << _W("Wrong insertion in a Cell.");
1416 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1419 else if (pITCurrent->isUserType()) // not a Scilab defined datatype, access field after field
1421 // call userType extract method
1425 types::InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(pEH->getArgs());
1426 if (pExtract == NULL)
1429 pExtract = callOverload(*pEH->getExp(), L"e", pEH->getArgs(), pITCurrent, NULL);
1432 if ((*iterFields)->getExp() == NULL)
1435 // extract a(x) and push_BACK to extract next level
1436 workFields.push_back(new ExpHistory(pEH, NULL, (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1437 workFields.back()->setReinsertion();
1442 // extract a(x) and push_FRONT to extract b from a(x)
1443 workFields.push_front(new ExpHistory(pEH, pEH->getExp(), NULL, pEH->getLevel(), pEH->isCellExp(), pExtract));
1444 workFields.front()->setReinsertion();
1449 // a.x, get string "x"
1450 std::wstring pwcsFieldname = (*iterFields)->getExpAsString();
1452 // create arg with next field
1453 types::typed_list* args = new types::typed_list();
1454 args->push_back(new types::String(pwcsFieldname.c_str()));
1457 // check if the field x is the last field
1458 std::list<ExpHistory*>::iterator iterFieldsNext(iterFields);
1460 if (iterFieldsNext == fields.end() && (*iterFields)->getArgs() == NULL)
1462 // a.x where x is the last field
1463 // insert directly in x instead of extract then insert
1464 ExpHistory* pEHNext = new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), _pAssignValue);
1465 pEHNext->setReinsertion(true);
1466 evalFields.push_back(pEHNext);
1467 if (workFields.empty())
1474 types::InternalType* pExtract = pITCurrent->getAs<types::UserType>()->extract(args);
1475 if (pExtract == NULL)
1478 pExtract = callOverload(*pEH->getExp(), L"e", args, pITCurrent, NULL);
1481 // append extraction of a.x for next level.
1482 workFields.push_back(new ExpHistory(pEH, (*iterFields)->getExp(), (*iterFields)->getArgs(), (*iterFields)->getLevel(), (*iterFields)->isCellExp(), pExtract));
1483 workFields.back()->setReinsertion();
1487 else if (pITCurrent->isCallable())
1490 types::typed_list out;
1491 types::typed_list in;
1492 types::optional_list opt;
1496 in = *pEH->getArgs();
1501 ret = pITCurrent->invoke(in, opt, 1, out, *pEH->getExp());
1503 catch (ast::InternalAbort& ia)
1507 catch (const ast::InternalError& ie)
1512 if (ret == false || out.size() != 1 || out[0]->isHandle() == false)
1515 char* strFName = wide_string_to_UTF8(pITCurrent->getAs<types::Callable>()->getName().c_str());
1516 os_sprintf(szError, _("Wrong insertion: insertion in output of '%s' is not allowed.\n"), strFName);
1519 wchar_t* wError = to_wide_string(szError);
1520 std::wstring err(wError);
1523 throw ast::InternalError(err, 999, pEH->getExp()->getLocation());
1526 pEH->setCurrent(out[0]);
1528 pEH->resetReinsertion();
1529 workFields.push_front(pEH);
1530 evalFields.pop_back();
1534 types::InternalType* pIT = new types::Struct(1, 1);
1535 pEH->setCurrent(pIT);
1536 pEH->setReinsertion();
1538 workFields.push_front(pEH);
1539 evalFields.pop_back();
1542 if (workFields.front()->getLevel() == (*iterFields)->getLevel())
1549 //*** insert what we have to assign ***//
1550 //*** in case where the last field is a CallExp ***//
1551 while (workFields.empty() == false)
1553 ExpHistory* pEH = workFields.front();
1554 evalFields.push_back(pEH);
1555 workFields.pop_front();
1557 types::typed_list* pArgs = pEH->getArgs();
1559 // should never occured
1560 if (pArgs == NULL || pArgs->size() == 0)
1562 std::wostringstream os;
1563 os << _W("Wrong insertion : Cannot insert without arguments.");
1564 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1567 if (pEH->isCellExp())
1569 types::Cell* pCell = pEH->getCurrent()->getAs<types::Cell>();
1570 // insert "something" in b{x}
1571 if ((*pArgs)[0]->isString())
1573 std::wostringstream os;
1574 os << _W("Wrong insertion in a Cell.");
1575 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1578 pCell->insertCell(pArgs, _pAssignValue);
1580 else if (pEH->getCurrent() && pEH->getCurrent()->isCallable())
1582 std::wostringstream os;
1583 os << _W("Unexpected redefinition of Scilab function.");
1584 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1588 // insert "something" in b(x,y)
1589 types::InternalType* pIT = insertionCall(*_pExp, pArgs, pEH->getCurrent(), _pAssignValue);
1592 std::wostringstream os;
1593 os << _W("Submatrix incorrectly defined.\n");
1594 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1597 pEH->setCurrent(pIT);
1601 //*** update fields ***//
1602 while (evalFields.empty() == false)
1604 ExpHistory* pEH = evalFields.back();
1605 if (pEH->reinsertMe())
1607 ExpHistory* pEHParent = pEH->getParent();
1609 if (pEHParent == NULL)
1613 pITMain->DecreaseRef();
1618 pITMain = pEH->getCurrent();
1619 pITMain->IncreaseRef();
1623 types::typed_list* pParentArgs = pEHParent->getArgs();
1624 if (pParentArgs == NULL || pEH->getWhereReinsert() != -1)
1626 types::InternalType* pParent = pEHParent->getCurrent();
1627 if (pParent->isStruct())
1629 types::Struct* pStruct = pParent->getAs<types::Struct>();
1630 pStruct->get(pEH->getWhereReinsert())->set(pEH->getExpAsString(), pEH->getCurrent());
1631 evalFields.pop_back();
1635 else if (pParent->isTList() || pParent->isMList())
1637 types::TList* pTL = pParent->getAs<types::TList>();
1640 pTL = pTL->set(pEH->getWhereReinsert(), pEH->getCurrent());
1641 pEHParent->setCurrent(pTL);
1642 evalFields.pop_back();
1648 if (pTL->exists(pEH->getExpAsString()))
1650 pTL = pTL->set(pEH->getExpAsString(), pEH->getCurrent());
1651 pEHParent->setCurrent(pTL);
1652 evalFields.pop_back();
1657 pParentArgs = new types::typed_list();
1658 pParentArgs->push_back(new types::String(pEH->getExpAsString().c_str()));
1661 else if (pParent->isCell())
1663 types::Cell* pCell = pParent->getAs<types::Cell>();
1664 if (pEHParent->isCellExp() && pEH->getWhereReinsert() != -1)
1666 // a{x}.b => reinsert b in a{x}
1667 pCell->set(pEH->getWhereReinsert(), pEH->getCurrent());
1668 pEHParent->setReinsertion();
1669 evalFields.pop_back();
1676 types::InternalType* pIT = insertionCall(*_pExp, pParentArgs, pEHParent->getCurrent(), pEH->getCurrent());
1679 std::wostringstream os;
1680 os << _W("Submatrix incorrectly defined.\n");
1681 throw ast::InternalError(os.str(), 999, _pExp->getLocation());
1684 pEHParent->setCurrent(pIT);
1685 if (pEHParent->getArgs() == NULL)
1691 if (pEH->getCurrent())
1693 pEH->getCurrent()->killMe();
1696 evalFields.pop_back();
1702 pITMain->DecreaseRef();
1703 ctx->put(spMainExp->getStack(), pITMain);
1706 if (!evalFields.empty())
1708 for (std::list<ExpHistory*>::const_iterator i = evalFields.begin(), end = evalFields.end(); i != end; i++)
1716 catch (const ast::InternalError error)
1720 pITMain->DecreaseRef();
1723 for (std::list<ExpHistory*>::reverse_iterator i = workFields.rbegin(); i != workFields.rend(); ++i)
1725 (*i)->setDeleteCurrent(true);
1729 for (std::list<ExpHistory*>::reverse_iterator i = evalFields.rbegin(); i != evalFields.rend(); ++i)
1731 (*i)->setDeleteCurrent(true);
1739 types::InternalType* insertionCall(const ast::Exp& e, types::typed_list* _pArgs, types::InternalType* _pVar, types::InternalType* _pInsert)
1741 types::InternalType* pOut = NULL;
1742 types::InternalType *pIL = NULL;
1743 //fisrt extract implicit list
1744 if (_pInsert->isColon())
1746 //double* pdbl = NULL;
1747 //_pInsert = new Double(-1, -1, &pdbl);
1749 pIL = types::Double::Identity(-1, -1);
1753 else if (_pInsert->isImplicitList())
1755 pIL = _pInsert->getAs<types::ImplicitList>()->extractFullMatrix();
1756 if (pIL && pIL->isDeletable())
1762 else if (_pInsert->isContainer() && _pInsert->isRef())
1764 //std::cout << "assign container type during insertion" << std::endl;
1765 //types::InternalType* pIL = _pInsert->clone();
1769 if (_pInsert->isDouble() && _pInsert->getAs<types::Double>()->isEmpty() && _pVar == NULL)
1771 // l(x) = [] when l is not defined => create l = []
1772 pOut = types::Double::Empty();
1774 else if (_pInsert->isDouble() && _pInsert->getAs<types::Double>()->isEmpty() && _pVar->isStruct() == false && _pVar->isList() == false)
1776 //insert [] so deletion except for Struct and List which can insert []
1777 if (_pVar->isHandle())
1779 types::GraphicHandle* pH = _pVar->getAs<types::GraphicHandle>();
1780 if ((*_pArgs)[0]->isString())
1782 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1784 types::typed_list in;
1785 types::typed_list out;
1786 types::optional_list opt;
1790 in.push_back(_pInsert);
1792 types::Function* pCall = (types::Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
1793 types::Callable::ReturnValue ret = pCall->call(in, opt, 1, out);
1794 if (ret == types::Callable::OK)
1801 pOut = pH->insert(_pArgs, _pInsert);
1804 else if (_pVar->isStruct())
1806 pOut = _pVar->getAs<types::Struct>()->insert(_pArgs, _pInsert);
1808 else if (_pVar->isUserType())
1810 pOut = _pVar->getAs<types::UserType>()->insert(_pArgs, _pInsert);
1812 else if (_pInsert->isGenericType() && (_pInsert->isTList() == false && _pInsert->isMList() == false))
1814 pOut = _pVar->getAs<types::GenericType>()->remove(_pArgs);
1819 pOut = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
1822 else if (_pVar == NULL || (_pVar->isDouble() && _pVar->getAs<types::Double>()->getSize() == 0))
1824 //insert in a new variable or []
1825 //call static insert function
1826 //if _pVar == NULL and pArg is single string, it's a struct creation
1827 if ((*_pArgs)[0]->isString())
1829 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1830 types::Struct* pStr = new types::Struct(1, 1);
1832 if (_pArgs->size() != 1 || pS->isScalar() == false)
1839 std::wostringstream os;
1840 os << _W("Invalid Index.\n");
1841 throw ast::InternalError(os.str(), 999, e.getLocation());
1844 pStr->addField(pS->get(0));
1845 pStr->get(0)->set(pS->get(0), _pInsert);
1850 if (_pInsert->isGenericType() && (_pInsert->isTList() == false && _pInsert->isMList() == false))
1852 pOut = _pInsert->getAs<types::GenericType>()->insertNew(_pArgs);
1857 types::Double* pEmpty = types::Double::Empty();
1858 pOut = callOverload(e, L"i", _pArgs, _pInsert, pEmpty);
1865 //call type insert function
1866 types::InternalType* pRet = NULL;
1869 if (_pArgs == NULL || _pArgs->size() == 0)
1871 std::wostringstream os;
1872 os << _W("Wrong insertion : Cannot insert without arguments.");
1873 throw ast::InternalError(os.str(), 999, e.getLocation());
1876 //check types compatibilties
1877 if (_pVar->isDouble() && _pInsert->isSparse())
1879 types::Sparse* pSp = _pInsert->getAs<types::Sparse>();
1880 types::Double* pD = new types::Double(pSp->getRows(), pSp->getCols(), pSp->isComplex());
1882 pRet = _pVar->getAs<types::GenericType>()->insert(_pArgs, pD);
1885 else if (_pVar->isSparse() && _pInsert->isDouble())
1887 pRet = _pVar->getAs<types::GenericType>()->insert(_pArgs, _pInsert);
1889 else if (_pVar->isSparseBool() && _pInsert->isBool())
1891 pRet = _pVar->getAs<types::GenericType>()->insert(_pArgs, _pInsert);
1893 else if (_pVar->isDouble() && _pInsert->isPoly())
1895 types::Double* pDest = _pVar->getAs<types::Double>();
1896 types::Polynom* pIns = _pInsert->getAs<types::Polynom>();
1897 int iSize = pDest->getSize();
1898 int* piRanks = new int[iSize];
1899 memset(piRanks, 0x00, iSize * sizeof(int));
1900 types::Polynom* pP = new types::Polynom(pIns->getVariableName(), pDest->getDims(), pDest->getDimsArray(), piRanks);
1902 pP->setComplex(pDest->isComplex());
1904 if (pP->isComplex())
1906 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1908 double dblR = pDest->get(idx);
1909 double dblI = pDest->getImg(idx);
1910 pP->get(idx)->setCoef(&dblR, &dblI);
1915 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1917 double dblR = pDest->get(idx);
1918 pP->get(idx)->setCoef(&dblR, NULL);
1922 pRet = pP->insert(_pArgs, pIns);
1924 else if (_pVar->isPoly() && _pInsert->isDouble())
1926 types::Polynom* pDest = _pVar->getAs<types::Polynom>();
1927 types::Double* pIns = _pInsert->getAs<types::Double>();
1928 bool isComplexIns = pIns->isComplex();
1929 int iSize = pIns->getSize();
1930 int* piRanks = new int[iSize];
1931 memset(piRanks, 0x00, iSize * sizeof(int));
1933 //create a new polynom with Double to insert it into dest polynom
1934 types::Polynom* pP = new types::Polynom(pDest->getVariableName(), pIns->getDims(), pIns->getDimsArray(), piRanks);
1939 double* pR = pIns->get();
1940 double* pI = pIns->getImg();
1941 types::SinglePoly** pSP = pP->get();
1942 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1944 double dblR = pR[idx];
1945 double dblI = pI[idx];
1946 pSP[idx]->setComplex(true);
1947 pSP[idx]->setCoef(&dblR, &dblI);
1952 double* pdblR = pIns->get();
1953 types::SinglePoly** pSP = pP->get();
1954 for (int idx = 0 ; idx < pP->getSize() ; idx++)
1956 double dblR = pdblR[idx];
1957 pSP[idx]->setCoef(&dblR, NULL);
1961 pRet = pDest->insert(_pArgs, pP);
1964 else if (_pVar->isStruct())
1966 types::Struct* pStruct = _pVar->getAs<types::Struct>();
1967 // insert something in a field of a struct
1968 if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
1971 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
1972 if (pS->isScalar() == false)
1979 std::wostringstream os;
1980 os << _W("Invalid Index.\n");
1981 throw ast::InternalError(os.str(), 999, e.getLocation());
1984 if (_pInsert->isListDelete())
1986 /* Remove a field */
1987 pStruct = pStruct->removeField(pS->get(0));
1992 pStruct = pStruct->addField(pS->get(0));
1993 for (int i = 0; i < pStruct->getSize(); i++)
1995 pStruct->get(i)->set(pS->get(0), _pInsert);
2000 else // insert something in a struct
2002 if (_pInsert->isStruct())
2004 types::String* pStrFieldsName = pStruct->getFieldNames();
2005 types::Struct* pStructInsert = _pInsert->clone()->getAs<types::Struct>();
2006 types::String* pStrInsertFieldsName = pStructInsert->getFieldNames();
2007 types::Struct* pStructRet = NULL;
2009 // if not an empty struct
2012 // insert fields of pStruct in pStructInsert
2013 for (int i = pStrFieldsName->getSize(); i > 0; i--)
2015 if (pStructInsert->exists(pStrFieldsName->get(i - 1)) == false)
2017 pStructInsert->addFieldFront(pStrFieldsName->get(i - 1));
2021 std::wstring pwcsField = pStrFieldsName->get(i - 1);
2022 types::List* pLExtract = pStructInsert->extractFieldWithoutClone(pwcsField);
2024 for (int i = 0; i < pLExtract->getSize(); i++)
2026 // protect element wich are not cloned before call removeField.
2027 pLExtract->get(i)->IncreaseRef();
2030 pStructInsert->removeField(pwcsField);
2031 pStructInsert->addFieldFront(pwcsField);
2033 for (int i = 0; i < pLExtract->getSize(); i++)
2035 // set elements in the new position
2036 pStructInsert->get(i)->set(pwcsField, pLExtract->get(i));
2037 pLExtract->get(i)->DecreaseRef();
2040 pLExtract->killMe();
2044 pStrFieldsName->killMe();
2047 // insert elements in following pArgs
2048 pRet = pStruct->insert(_pArgs, pStructInsert);
2049 pStructRet = pRet->getAs<types::Struct>();
2051 pStructInsert->killMe();
2053 // insert fields of pStructInsert in pRet
2054 for (int i = 0; i < pStrInsertFieldsName->getSize(); i++)
2056 if (pStructRet->exists(pStrInsertFieldsName->get(i)) == false)
2058 pStructRet->addField(pStrInsertFieldsName->get(i));
2062 pStrInsertFieldsName->killMe();
2066 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2070 else if (_pVar->isTList() || _pVar->isMList())
2072 types::TList* pTL = _pVar->getAs<types::TList>();
2073 if (_pArgs->size() == 1)
2075 if ((*_pArgs)[0]->isString())
2078 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
2079 if (pS->isScalar() == false)
2087 std::wostringstream os;
2088 os << _W("Invalid Index.\n");
2089 throw ast::InternalError(os.str(), 999, e.getLocation());
2092 if (_pInsert->isListDelete())
2094 return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2097 if (pTL->exists(pS->get(0)))
2099 pRet = pTL->set(pS->get(0), _pInsert);
2103 return callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2108 //std::wstring function_name = L"%l_e";
2110 //_pInsert->IncreaseRef();
2111 //in.push_back(_pInsert);
2113 //Overload::call(function_name, in, 1, out, &exec);
2114 //_pInsert->DecreaseRef();
2116 //if (out.size() != 0)
2125 if (_pVar->isMList())
2127 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2131 // In case where pTL is in several scilab variable,
2132 // we have to clone it for keep the other variables unchanged.
2133 if (pTL->getRef() > 1)
2135 pTL = pTL->clone()->getAs<types::TList>();
2138 pRet = pTL->insert(_pArgs, _pInsert);
2140 // If we have inserted something else than a String
2141 // in the first element, the TList have to be a List.
2142 if (pTL->get(0)->isString() == false)
2144 types::List* pL = new types::List();
2145 for (int i = 0; i < pTL->getSize(); i++)
2147 pL->append(pTL->get(i));
2158 if (_pVar->isMList())
2160 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2164 // call the overload if it exists.
2165 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2168 // else normal insert
2169 pRet = pTL->insert(_pArgs, _pInsert);
2174 else if (_pVar->isList())
2176 types::List* pL = NULL;
2177 // In case where pL is in several scilab variable,
2178 // we have to clone it for keep the other variables unchanged.
2179 if (_pVar->getRef() > 1)
2181 pL = _pVar->clone()->getAs<types::List>();
2182 pRet = pL->insert(_pArgs, _pInsert);
2187 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2192 pL = _pVar->getAs<types::List>();
2193 pRet = pL->insert(_pArgs, _pInsert);
2197 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2201 else if (_pVar->isHandle())
2203 if (_pArgs->size() == 1 && (*_pArgs)[0]->isString())
2206 types::GraphicHandle* pH = _pVar->getAs<types::GraphicHandle>();
2207 types::String *pS = (*_pArgs)[0]->getAs<types::String>();
2208 types::typed_list in;
2209 types::typed_list out;
2210 types::optional_list opt;
2214 in.push_back(_pInsert);
2216 types::Function* pCall = (types::Function*)symbol::Context::getInstance()->get(symbol::Symbol(L"set"));
2219 types::Callable::ReturnValue ret = pCall->call(in, opt, 1, out);
2220 if (ret == types::Callable::OK)
2226 throw ast::InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
2232 pRet = _pVar->getAs<types::GraphicHandle>()->insert(_pArgs, _pInsert);
2235 else if (_pVar->isUserType())
2237 for (int i = 0; i < _pArgs->size(); i++)
2239 if ((*_pArgs)[i]->isImplicitList())
2241 types::ImplicitList* pIL = (*_pArgs)[i]->getAs<types::ImplicitList>();
2242 if (pIL->isComputable())
2244 types::InternalType* pIT = pIL->extractFullMatrix();
2245 (*_pArgs)[i]->killMe();
2251 pRet = _pVar->getAs<types::UserType>()->insert(_pArgs, _pInsert);
2254 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2257 else if (_pVar->getType() == _pInsert->getType())
2259 pRet = _pVar->getAs<types::GenericType>()->insert(_pArgs, _pInsert);
2261 else if (_pVar->isCell())
2263 if (_pInsert->isCell() == false)
2266 std::wostringstream os;
2267 os << _W("Wrong insertion: A Cell expected: use {...} instead of (...).\n");
2268 throw ast::InternalError(os.str(), 999, e.getLocation());
2274 pRet = callOverload(e, L"i", _pArgs, _pInsert, _pVar);
2288 void callOnPrompt(void)
2290 static symbol::Variable* onPrompt = NULL;
2291 if (onPrompt == NULL)
2293 onPrompt = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"%onprompt"));
2296 types::InternalType* pOnPrompt = NULL;
2297 pOnPrompt = onPrompt->get();
2298 if (pOnPrompt != NULL && pOnPrompt->isCallable())
2300 StoreConsoleCommand("%onprompt()", 1);
2304 ast::Exp* callTyper(ast::Exp* _tree, std::wstring _msg)
2306 ast::Exp* newTree = NULL;
2307 unsigned char *newast = NULL;
2308 ast::SerializeVisitor* s = new ast::SerializeVisitor(_tree);
2309 ast::DeserializeVisitor* d = NULL;
2313 unsigned char* astbin = s->serialize();
2314 //call ocamlpro typer
2315 //char *newast = ocamlpro_typer(astbin);
2321 d = new ast::DeserializeVisitor(newast);
2322 newTree = d->deserialize();
2326 std::wstring msgS(_msg + L" serialize");
2327 std::wstring msgD(_msg + L" deserialize");
2331 unsigned char* astbin = s->serialize();
2332 timer.check(msgS.c_str());
2334 //call ocamlpro typer
2335 //char *newast = ocamlpro_typer(astbin);
2342 d = new ast::DeserializeVisitor(newast);
2343 newTree = d->deserialize();
2344 timer.check(msgD.c_str());
2353 std::string printExp(std::ifstream& _File, ast::Exp* _pExp, const std::string& _stPrompt, int* _piLine /* in/out */, int* _piCol /* in/out */, std::string& _stPreviousBuffer)
2355 Location loc = _pExp->getLocation();
2358 //for multiple expression on same line
2359 //_stPreviousBuffer will not be updated
2361 //bypass previous lines
2362 for (int i = *_piLine; i < loc.first_line - 1; i++)
2366 if ((*_piLine) != (loc.first_line - 1))
2369 if (ConfigVariable::isPrintCompact() == false)
2371 printLine("", "", true);
2374 std::getline(_File, _stPreviousBuffer);
2377 if (loc.first_line == loc.last_line)
2379 //expression on 1-line
2380 int iStart = loc.first_column - 1;
2381 int iEnd = loc.last_column - 1;
2382 int iLen = iEnd - iStart;
2384 int iCopyLen = iEnd - *_piCol;
2385 std::string strLastLine(_stPreviousBuffer.c_str() + *_piCol, iCopyLen);
2387 int iLineLen = (int)_stPreviousBuffer.size();
2388 bool bStart = iStart == 0 || *_piCol == 0;
2389 bool bEnd = iStart + iExpLen == iLineLen;
2396 printLine(_stPrompt, strLastLine, true);
2401 printLine(_stPrompt, strLastLine, false);
2402 *_piCol = loc.last_column - 1;
2405 else //middle of line
2409 printLine("", strLastLine, true);
2414 printLine("", strLastLine, false);
2415 *_piCol = loc.last_column - 1;
2422 int iStart = loc.first_column - 1;
2423 bool bStart = iStart == 0 || *_piCol == 0;
2425 std::string strLastLine(_stPreviousBuffer.c_str() + *_piCol);
2430 printLine(_stPrompt, strLastLine, true);
2434 printLine("", strLastLine, true);
2437 bool isCompact = ConfigVariable::isPrintCompact();
2438 ConfigVariable::setPrintCompact(true);
2441 for (int i = loc.first_line; i < (loc.last_line - 1); i++)
2444 std::getline(_File, _stPreviousBuffer);
2445 // dont print empty line of function body
2446 if (_stPreviousBuffer.size() != 0)
2448 printLine(_stPrompt, _stPreviousBuffer.c_str(), true);
2453 std::getline(_File, _stPreviousBuffer);
2456 int iSize = loc.last_column - 1;
2457 std::string stLastLine(_stPreviousBuffer.c_str(), iSize);
2458 int iLineLen = (int)_stPreviousBuffer.size();
2459 if (iLineLen == iSize)
2461 printLine(_stPrompt, stLastLine, true);
2466 printLine(_stPrompt, stLastLine, false);
2467 *_piCol = loc.last_column - 1;
2470 ConfigVariable::setPrintCompact(isCompact);
2473 return _stPreviousBuffer;
2476 void printLine(const std::string& _stPrompt, const std::string& _stLine, bool _bLF)
2479 int size = _stPrompt.size();
2480 if (size && ConfigVariable::isPrintCompact() == false)
2493 scilabWrite(st.c_str());
2495 /*--------------------------------------------------------------------------*/