Merge remote-tracking branch 'origin/master' into jit
[scilab.git] / scilab / modules / ast / src / cpp / types / callable.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
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 <vector>
15 #include "callable.hxx"
16 #include "configvariable.hxx"
17 #include "exp.hxx"
18 #include "scilabexception.hxx"
19
20 namespace types
21 {
22
23 bool Callable::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, const ast::Exp & e)
24 {
25     //check recursion before try catch, to make difference with  errors
26     if (ConfigVariable::increaseRecursion())
27     {
28         //reset previous error before call function
29         ConfigVariable::resetError();
30         //update verbose";" flag
31         ConfigVariable::setVerbose(e.isVerbose());
32         // add line and function name in where
33         int iFirstLine = e.getLocation().first_line;
34         ConfigVariable::where_begin(iFirstLine + 1 - ConfigVariable::getMacroFirstLines(), iFirstLine, this);
35         Callable::ReturnValue Ret;
36
37         try
38         {
39             Ret = call(in, opt, _iRetCount, out);
40             ConfigVariable::where_end();
41             ConfigVariable::decreaseRecursion();
42         }
43         catch (ast::InternalError & ie)
44         {
45             ConfigVariable::where_end();
46             ConfigVariable::setLastErrorFunction(getName());
47             ConfigVariable::decreaseRecursion();
48             throw ie;
49         }
50         catch (ast::InternalAbort & ia)
51         {
52             ConfigVariable::where_end();
53             ConfigVariable::setLastErrorFunction(getName());
54             ConfigVariable::decreaseRecursion();
55             throw ia;
56         }
57
58         if (Ret == Callable::Error)
59         {
60             ConfigVariable::setLastErrorFunction(getName());
61             ConfigVariable::setLastErrorLine(e.getLocation().first_line);
62             throw ast::InternalError(ConfigVariable::getLastErrorMessage(), ConfigVariable::getLastErrorNumber(), e.getLocation());
63         }
64     }
65     else
66     {
67         throw ast::RecursionException();
68     }
69     return true;
70 }
71 }