203e6ae6532252d8209022c4e6b5277775f8ed5f
[scilab.git] / scilab / modules / ast / src / cpp / types / 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
13 extern "C"
14 {
15 #include "stdarg.h"
16 #include "os_string.h"
17 #include "sci_malloc.h"
18 #include "sciprint.h"
19 }
20
21 #include "configvariable.hxx"
22 #include "localization.hxx"
23 #include "callable.hxx"
24 #include "overload.hxx"
25 #include "context.hxx"
26 #include "scilabexception.hxx"
27
28 std::wstring Overload::buildOverloadName(std::wstring _stFunctionName, types::typed_list &in, int /*_iRetCount*/, bool _isOperator, bool _truncated)
29 {
30     std::wstring stType0 = in[0]->getShortTypeStr();
31
32     if (_truncated)
33     {
34         stType0 = stType0.substr(0, 8);
35     }
36
37     switch (in.size())
38     {
39         case 0 :
40             return L"%_" + _stFunctionName;
41         case 2:
42             if (_isOperator)
43             {
44                 return L"%" + stType0 + L"_" + _stFunctionName + L"_" + in[1]->getShortTypeStr();
45             }
46         default:
47             return L"%" + stType0 + L"_" + _stFunctionName;
48     }
49     return _stFunctionName;
50 }
51
52 types::Function::ReturnValue Overload::generateNameAndCall(std::wstring _stFunctionName, types::typed_list &in, int _iRetCount, types::typed_list &out, ast::ConstVisitor *_execMe, bool _isOperator)
53 {
54     std::wstring stFunc = buildOverloadName(_stFunctionName, in, _iRetCount, _isOperator);
55     types::Function::ReturnValue ret = types::Function::Error;
56     try
57     {
58         ret = call(stFunc, in, _iRetCount, out, _execMe, _isOperator);
59     }
60     catch (ast::ScilabError se)
61     {
62         std::wstring stFunc2 = buildOverloadName(_stFunctionName, in, _iRetCount, _isOperator, true);
63         ret = call(stFunc2, in, _iRetCount, out, _execMe, _isOperator);
64         if (ret == types::Function::OK && ConfigVariable::getWarningMode())
65         {
66             char* pstFunc2 = wide_string_to_UTF8(stFunc2.c_str());
67             char* pstFunc = wide_string_to_UTF8(stFunc.c_str());
68             sciprint(_("Warning : please rename your overloaded function\n \"%s\" to \"%s\"\n"), pstFunc2, pstFunc);
69             FREE(pstFunc);
70             FREE(pstFunc2);
71         }
72     }
73     return ret;
74 }
75
76 types::Function::ReturnValue Overload::call(std::wstring _stOverloadingFunctionName, types::typed_list &in, int _iRetCount, types::typed_list &out, ast::ConstVisitor *_execMe, bool _isOperator)
77 {
78     types::InternalType *pIT = symbol::Context::getInstance()->get(symbol::Symbol(_stOverloadingFunctionName));
79
80     if (pIT == NULL || pIT->isCallable() == false)
81     {
82         char pstError1[512];
83         char pstError2[512];
84         char *pstFuncName = wide_string_to_UTF8(_stOverloadingFunctionName.c_str());
85         wchar_t* pwstError = NULL;
86         if (_isOperator)
87         {
88             os_sprintf(pstError2, _("check or define function %s for overloading.\n"), pstFuncName);
89             os_sprintf(pstError1, "%s%s", _("Undefined operation for the given operands.\n"), pstError2);
90             pwstError = to_wide_string(pstError1);
91             std::wstring wstError(pwstError);
92             FREE(pwstError);
93             FREE(pstFuncName);
94             throw ast::ScilabError(wstError, 999, Location());
95         }
96         else
97         {
98             os_sprintf(pstError2, _("  check arguments or define function %s for overloading.\n"), pstFuncName);
99             os_sprintf(pstError1, "%s%s", _("Function not defined for given argument type(s),\n"), pstError2);
100             pwstError = to_wide_string(pstError1);
101             std::wstring wstError(pwstError);
102             FREE(pwstError);
103             FREE(pstFuncName);
104             throw ast::ScilabError(wstError, 999, Location());
105         }
106     }
107     types::Callable *pCall = pIT->getAs<types::Callable>();
108     try
109     {
110         types::optional_list opt;
111         return pCall->call(in, opt, _iRetCount, out, _execMe);
112     }
113     catch (ast::ScilabMessage sm)
114     {
115         if (pCall->isMacro() || pCall->isMacroFile())
116         {
117             wchar_t szError[bsiz];
118             os_swprintf(szError, bsiz, _W("at line % 5d of function %ls called by :\n").c_str(), sm.GetErrorLocation().first_line, pCall->getName().c_str());
119             throw ast::ScilabMessage(szError);
120         }
121         else
122         {
123             throw sm;
124         }
125     }
126 }
127
128 std::wstring Overload::getNameFromOper(ast::OpExp::Oper _oper)
129 {
130     switch (_oper)
131     {
132             /* standard operators */
133         case ast::OpExp::plus :
134             return std::wstring(L"a");
135         case ast::OpExp::unaryMinus :
136         case ast::OpExp::minus :
137             return std::wstring(L"s");
138         case ast::OpExp::times :
139             return std::wstring(L"m");
140         case ast::OpExp::rdivide :
141             return std::wstring(L"r");
142         case ast::OpExp::ldivide :
143             return std::wstring(L"l");
144         case ast::OpExp::power :
145             return std::wstring(L"p");
146             /* dot operators */
147         case ast::OpExp::dottimes :
148             return std::wstring(L"x");
149         case ast::OpExp::dotrdivide :
150             return std::wstring(L"d");
151         case ast::OpExp::dotldivide :
152             return std::wstring(L"q");
153         case ast::OpExp::dotpower :
154             return std::wstring(L"j");
155             /* Kron operators */
156         case ast::OpExp::krontimes :
157             return std::wstring(L"k");
158         case ast::OpExp::kronrdivide :
159             return std::wstring(L"y");
160         case ast::OpExp::kronldivide :
161             return std::wstring(L"z");
162             /* Control Operators ??? */
163         case ast::OpExp::controltimes :
164             return std::wstring(L"u");
165         case ast::OpExp::controlrdivide :
166             return std::wstring(L"v");
167         case ast::OpExp::controlldivide :
168             return std::wstring(L"w");
169         case ast::OpExp::eq :
170             return std::wstring(L"o");
171         case ast::OpExp::ne :
172             return std::wstring(L"n");
173         case ast::OpExp::lt :
174             return std::wstring(L"1");
175         case ast::OpExp::le :
176             return std::wstring(L"3");
177         case ast::OpExp::gt :
178             return std::wstring(L"2");
179         case ast::OpExp::ge :
180             return std::wstring(L"4");
181         case ast::OpExp::logicalAnd :
182             return std::wstring(L"h");
183         case ast::OpExp::logicalOr :
184             return std::wstring(L"g");
185         case ast::OpExp::logicalShortCutAnd :
186             return std::wstring(L"h");
187         case ast::OpExp::logicalShortCutOr :
188             return std::wstring(L"g");
189         default :
190             return std::wstring(L"???");
191     }
192 }