Refactoring of ScilabException in AST, exec, execstr.
[scilab.git] / scilab / modules / api_scilab / src / cpp / overload.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
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 extern "C"
13 {
14 #include "stdarg.h"
15 #include "localization.h"
16 #include "os_swprintf.h"
17 }
18
19 #include "callable.hxx"
20 #include "overload.hxx"
21 #include "context.hxx"
22 #include "scilabexception.hxx"
23
24 std::wstring Overload::buildOverloadName(std::wstring _stFunctionName, types::typed_list &in, int _iRetCount)
25 {
26     switch(in.size())
27     {
28     case 0 :
29         return L"%_" + _stFunctionName;
30     case 1:
31         return L"%" + in[0]->getShortTypeStr() + L"_" + _stFunctionName;
32     case 2:
33         return L"%" + in[0]->getShortTypeStr() + L"_" + _stFunctionName + L"_" + in[1]->getShortTypeStr();
34     default :
35         throw ast::ScilabError(L"Don't know how to overload " + _stFunctionName, 999, *new Location());
36     }
37     return _stFunctionName;
38 }
39
40 types::Function::ReturnValue Overload::generateNameAndCall(std::wstring _stFunctionName, types::typed_list &in, int _iRetCount, types::typed_list &out, ast::ConstVisitor *_execMe)
41 {
42     return call(buildOverloadName(_stFunctionName, in, _iRetCount), in, _iRetCount, out, _execMe);
43 }
44
45 types::Function::ReturnValue Overload::call(std::wstring _stOverloadingFunctionName, types::typed_list &in, int _iRetCount, types::typed_list &out, ast::ConstVisitor *_execMe)
46 {
47     types::InternalType *pIT = symbol::Context::getInstance()->get(symbol::Symbol(_stOverloadingFunctionName));
48
49     if(pIT == NULL || pIT->isCallable() == false)
50     {
51         throw ast::ScilabError(_W("check or define function ") + _stOverloadingFunctionName + _W(" for overloading.\n\n"), 999, *new Location());
52     }
53     types::Callable *pCall = pIT->getAs<types::Callable>();
54     try
55     {
56         return pCall->call(in, _iRetCount, out, _execMe);
57     }
58     catch (ScilabMessage sm)
59     {
60         if(pCall->isMacro() || pCall->isMacroFile())
61         {
62             wchar_t szError[bsiz];
63             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n"), sm.GetErrorLocation().first_line, pCall->getName().c_str());
64             throw ScilabMessage(szError);
65         }
66         else
67         {
68             throw sm;
69         }
70     }
71 }
72
73 std::wstring Overload::getNameFromOper(ast::OpExp::Oper _oper)
74 {
75     switch (_oper)
76     {
77         /* standard operators */
78     case OpExp::plus :
79         return std::wstring(L"a");
80     case OpExp::minus :
81         return std::wstring(L"s");
82     case OpExp::times :
83         return std::wstring(L"m");
84     case OpExp::rdivide :
85         return std::wstring(L"r");
86     case OpExp::ldivide :
87         return std::wstring(L"l");
88     case OpExp::power :
89         return std::wstring(L"p");
90         /* dot operators */
91     case OpExp::dottimes :
92         return std::wstring(L"x");
93     case OpExp::dotrdivide :
94         return std::wstring(L"d");
95     case OpExp::dotldivide :
96         return std::wstring(L"q");
97     case OpExp::dotpower :
98         return std::wstring(L"j");
99         /* Kron operators */
100     case OpExp::krontimes :
101         return std::wstring(L"k");
102     case OpExp::kronrdivide :
103         return std::wstring(L"y");
104     case OpExp::kronldivide :
105         return std::wstring(L"z");
106         /* Control Operators ??? */
107     case OpExp::controltimes :
108         return std::wstring(L"u");
109     case OpExp::controlrdivide :
110         return std::wstring(L"v");
111     case OpExp::controlldivide :
112         return std::wstring(L"w");
113     case OpExp::eq :
114         return std::wstring(L"o");
115     case OpExp::ne :
116         return std::wstring(L"n");
117     case OpExp::lt :
118         return std::wstring(L"1");
119     case OpExp::le :
120         return std::wstring(L"3");
121     case OpExp::gt :
122         return std::wstring(L"2");
123     case OpExp::ge :
124         return std::wstring(L"4");
125     case OpExp::logicalAnd :
126         return std::wstring(L"h");
127     case OpExp::logicalOr :
128         return std::wstring(L"g");
129     case OpExp::logicalShortCutAnd :
130         return std::wstring(L"h");
131     case OpExp::logicalShortCutOr :
132         return std::wstring(L"g");
133     default :
134         return std::wstring(L"???");
135     }
136 }
137
138 wstring formatString(const wstring& wstFormat, ...)
139 {
140     wchar_t pwstTemp[1024];
141     va_list arglist;
142     va_start(arglist, wstFormat);
143     int iLen = os_swprintf(pwstTemp, 1024, wstFormat.c_str(), arglist);
144     va_end(arglist);
145
146     return wstring(pwstTemp, iLen);
147 }