[opengtl-commits] [722] implement selection of the best overloaded function |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/opengtl-commits Archives
]
Revision: 722
Author: cyrille
Date: 2009-04-11 15:53:23 +0200 (Sat, 11 Apr 2009)
Log Message:
-----------
implement selection of the best overloaded function
Modified Paths:
--------------
trunk/OpenGTL/OpenGTL/GTLCore/ParserBase_p.cpp
Modified: trunk/OpenGTL/OpenGTL/GTLCore/ParserBase_p.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/ParserBase_p.cpp 2009-04-11 13:52:08 UTC (rev 721)
+++ trunk/OpenGTL/OpenGTL/GTLCore/ParserBase_p.cpp 2009-04-11 13:53:23 UTC (rev 722)
@@ -1438,13 +1438,13 @@
{
GTL_ASSERT( _functions.size() > 0 );
GTL_ASSERT( *_selectedFunction == 0 );
+ std::size_t realParameterCount = firstParameter + _expressions.size();
if( _functions.size() == 1 )
{
GTLCore::Function* function = _functions.front();
- std::size_t realNumber = firstParameter + _expressions.size();
- GTL_DEBUG( function->name().toString() << " " << function->d->data->minimumParameters() << " " << realNumber << " " << function->d->data->maximumParameters() );
- if( function->d->data->minimumParameters() > realNumber
- or realNumber > function->d->data->maximumParameters() )
+ GTL_DEBUG( function->name().toString() << " " << function->d->data->minimumParameters() << " " << realParameterCount << " " << function->d->data->maximumParameters() );
+ if( function->d->data->minimumParameters() > realParameterCount
+ or realParameterCount > function->d->data->maximumParameters() )
{
reportError("Invalid number of arguments for function: " + function->name().toString() + ".", currentToken());
return _expressions;
@@ -1452,10 +1452,82 @@
*_selectedFunction = function;
} else {
GTL_ABORT("Unimplemented");
+ GTLCore::Function* bestFunction = 0;
+ int bestLosslessConversionCount = _expressions.size() + 1;
+ int bestLossConversionCount = _expressions.size() + 1;
+ foreach( GTLCore::Function* function, _functions)
+ {
+ GTL_DEBUG("Test for " << *function);
+ if( function->d->data->minimumParameters() <= realParameterCount
+ and realParameterCount <= function->d->data->maximumParameters() )
+ {
+ GTL_DEBUG("Good range of arguments");
+ int posArg = 0;
+ int currentLossLessConversionCount = 0;
+ int currentLossConversionCount = 0;
+ bool canUse = true;
+ foreach( AST::Expression* expression, _expressions)
+ {
+ if( function->parameters()[ posArg + firstParameter ].output() )
+ {
+ if( not dynamic_cast< AST::AccessorExpression* >( expression ) )
+ {
+ // Not an accessor, meaning we can't use that function since the parameter is an output
+ canUse = false;
+ break;
+ }
+ }
+ ConvertCenter::ConversionQuality cq = d->compiler->convertCenter()->conversionQuality( expression->type(), function->parameters()[ posArg + firstParameter ].type());
+ GTL_DEBUG("Quality for " << posArg << " " << cq);
+ if( cq == ConvertCenter::NOT_CONVERTIBLE )
+ {
+ canUse = false;
+ break;
+ } else {
+ switch(cq)
+ {
+ case ConvertCenter::NOT_CONVERTIBLE:
+ GTL_ABORT("Shouldn't be possible");
+ case ConvertCenter::NONEEDED_CONVERSION:
+ break;
+ case ConvertCenter::LOSS_CONVERSION:
+ ++currentLossConversionCount;
+ break;
+ case ConvertCenter::LOSSLESS_CONVERSION:
+ ++currentLossLessConversionCount;
+ break;
+ }
+ }
+ ++posArg;
+ }
+ if(canUse )
+ {
+ if( currentLossLessConversionCount == bestLosslessConversionCount and currentLossConversionCount == bestLossConversionCount )
+ {
+ // Can't know which function to use
+ bestFunction = 0;
+ } else if( currentLossConversionCount < bestLossConversionCount or (currentLossLessConversionCount < bestLosslessConversionCount and currentLossConversionCount <= bestLossConversionCount ) ) {
+ bestFunction = function;
+ bestLosslessConversionCount = currentLossLessConversionCount;
+ bestLossConversionCount = currentLossConversionCount;
+ }
+ }
+ }
+ }
+ if( bestFunction )
+ {
+ GTL_DEBUG("Best function " << *bestFunction);
+ *_selectedFunction = bestFunction;
+ } else {
+ *_selectedFunction = 0;
+ reportError("Can't find which overloaded functions of '" + _functions.front()->name().toString() + "' to use.", currentToken() );
+ return _expressions;
+ }
}
// Attempt conversion
std::list<AST::Expression*> convertedExpressions;
GTLCore::Function* function = *_selectedFunction;
+ GTL_ASSERT(function);
foreach( AST::Expression* expression, _expressions )
{
int posArg = convertedExpressions.size();
@@ -1463,6 +1535,7 @@
function->parameters()[ posArg + firstParameter ].type() );
if( not expression )
{
+ *_selectedFunction = 0;
reportError("Can't convert parameter " + String::number( posArg + 1 ), d->currentToken );
return convertedExpressions;
}
@@ -1471,6 +1544,7 @@
{
if( not dynamic_cast< AST::AccessorExpression* >( expression ) )
{
+ *_selectedFunction = 0;
reportError( "Parameter of function '" + function->name().toString() + "' is an output parameter and requires a variable as argument", d->currentToken );
}
}