Use a stack to manage "where" location
[scilab.git] / scilab / modules / ast / src / cpp / types / mlist.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
4  *
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
10  *
11  */
12
13 #include <sstream>
14 #include "mlist.hxx"
15 #include "callable.hxx"
16 #include "overload.hxx"
17
18 #ifndef NDEBUG
19 #include "inspector.hxx"
20 #endif
21
22 namespace types
23 {
24 bool MList::invoke(typed_list & in, optional_list & /*opt*/, int /*_iRetCount*/, typed_list & out, ast::ConstVisitor & execFunc, const ast::Exp & /*e*/)
25 {
26     if (in.size() == 0)
27     {
28         out.push_back(this);
29         return true;
30     }
31     else if (in.size() == 1)
32     {
33         InternalType * arg = in[0];
34         InternalType* _out = NULL;
35         if (arg->isString())
36         {
37             std::list<std::wstring> stFields;
38             String * pString = arg->getAs<types::String>();
39             for (int i = 0; i < pString->getSize(); ++i)
40             {
41                 stFields.push_back(pString->get(i));
42             }
43
44             _out = extractStrings(stFields);
45
46             List* pList = _out->getAs<types::List>();
47             for (int i = 0; i < pList->getSize(); i++)
48             {
49                 out.push_back(pList->get(i));
50             }
51
52             delete pList;
53         }
54
55         if (!out.empty())
56         {
57             return true;
58         }
59     }
60
61     Callable::ReturnValue ret;
62     // Overload of extraction need
63     // the mlist from where we extract
64     this->IncreaseRef();
65     in.push_back(this);
66
67     try
68     {
69         ret = Overload::call(L"%" + getShortTypeStr() + L"_e", in, 1, out, &execFunc);
70     }
71     catch (ast::ScilabError & /*se*/)
72     {
73         ret = Overload::call(L"%l_e", in, 1, out, &execFunc);
74     }
75
76     // Remove this from "in" for keep "in" unchanged.
77     this->DecreaseRef();
78     in.pop_back();
79
80     if (ret == Callable::Error)
81     {
82         throw ast::ScilabError();
83     }
84
85     return true;
86 }
87 }