zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #19656
[Merge] lp:~zorba-coders/zorba/hof-next into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/hof-next into lp:zorba.
Commit message:
fixed function coersion
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/hof-next/+merge/155722
fixed function coersion
--
https://code.launchpad.net/~zorba-coders/zorba/hof-next/+merge/155722
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2013-03-27 09:32:22 +0000
+++ src/compiler/translator/translator.cpp 2013-03-27 12:42:22 +0000
@@ -1517,14 +1517,21 @@
PROMOTE_FUNC_PARAM,
func->getName());
}
+ else if (paramType->type_kind() == XQType::FUNCTION_TYPE_KIND)
+ {
+ // function coercion
+ argExpr = wrap_in_coercion(paramType, argExpr, loc);
+
+ xqtref_t cardType = tm->create_any_item_type(paramType->get_quantifier());
+
+ argExpr = wrap_in_type_match(argExpr,
+ cardType,
+ loc,
+ TREAT_FUNC_PARAM,
+ func->getName());
+ }
else
{
- if (paramType->type_kind() == XQType::FUNCTION_TYPE_KIND)
- {
- // function coercion
- argExpr = wrap_in_coercion(paramType, argExpr, loc, theCCB);
- }
-
argExpr = wrap_in_type_match(argExpr,
paramType,
loc,
@@ -1538,83 +1545,94 @@
/*******************************************************************************
+ The coersion expr is a flwor that looks like this:
+
+ for $fi in argExpr
+ return function($p1 as t1, ... $pn as tn) { $fi(p1, ..., pn) }
********************************************************************************/
expr* wrap_in_coercion(
xqtref_t targetType,
- expr* theExpr,
- const QueryLoc& loc,
- CompilerCB* theCCB,
- bool is_func_return = false)
+ expr* argExpr,
+ const QueryLoc& loc)
{
- const FunctionXQType* func_type = static_cast<const FunctionXQType*>(targetType.getp());
-
- // Create the dynamic call body
-
- function_item_expr* fiExpr =
+ const FunctionXQType* funcType =
+ static_cast<const FunctionXQType*>(targetType.getp());
+
+ xqtref_t returnType = funcType->get_return_type();
+
+ push_scope();
+
+ flwor_expr* coersionFlwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
+ for_clause* fiClause = wrap_in_forclause(argExpr, NULL);
+ var_expr* fiVar = fiClause->get_var();
+ coersionFlwor->add_clause(fiClause);
+
+ function_item_expr* inlineFuncExpr =
CREATE(function_item)(theRootSctx, theUDF, loc, true, false, true);
- push_nodestack(fiExpr);
-
- push_scope();
-
- // handle the function item expression
- flwor_expr* fnItem_flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
- for_clause* fnItem_fc = wrap_in_forclause(theExpr, NULL);
- var_expr* fnItem_var = fnItem_fc->get_var();
- fnItem_flwor->add_clause(fnItem_fc);
- var_expr* inner_subst_var = bind_var(loc, fnItem_var->get_name(), var_expr::hof_var);
- fiExpr->add_variable(fnItem_var, inner_subst_var, fnItem_var->get_name(), 0 /*var is not global*/);
-
- // bind the function item variable in the inner flwor
- flwor_expr* inner_flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
-
- // Handle parameters. For each parameter, a let binding is added to the inner flwor.
+ coersionFlwor->set_return_expr(inlineFuncExpr);
+
+ var_expr* fiSubstVar = bind_var(loc, fiVar->get_name(), var_expr::hof_var);
+
+ inlineFuncExpr->add_variable(fiVar, fiSubstVar, fiVar->get_name(), 0);
+
+ // Create the inline udf obj.
+ user_function_t inlineUDF =
+ new user_function(loc,
+ signature(function_item_expr::create_inline_fname(loc),
+ funcType->get_param_types(),
+ returnType),
+ NULL,
+ SIMPLE_EXPR,
+ theCCB);
+
+ inlineFuncExpr->set_function(inlineUDF);
+
+ std::vector<var_expr*> argVars;
std::vector<expr*> arguments; // Arguments to the dynamic function call
- for(csize i = 0; i < func_type->get_number_params(); i++)
- {
- xqtref_t paramType = func_type->operator[](i);
-
- var_expr* arg_var = create_temp_var(loc, var_expr::arg_var);
- var_expr* subst_var = bind_var(loc, arg_var->get_name(), var_expr::let_var);
- let_clause* lc = wrap_in_letclause(&*arg_var, subst_var);
-
- arg_var->set_param_pos(inner_flwor->num_clauses());
- arg_var->set_type(paramType);
-
- inner_flwor->add_clause(lc);
-
- arguments.push_back(CREATE(wrapper)(theRootSctx, theUDF, loc, subst_var));
- }
-
- if (inner_flwor->num_clauses() == 0)
- {
- inner_flwor = NULL;
+ csize numParams = funcType->get_number_params();
+ for(csize i = 0; i < numParams; ++i)
+ {
+ xqtref_t paramType = funcType->operator[](i);
+
+ var_expr* argVar = create_temp_var(loc, var_expr::arg_var);
+ argVar->set_param_pos(i);
+ argVar->set_type(paramType);
+ argVars.push_back(argVar);
+
+ expr* arg = CREATE(wrapper)(theRootSctx, theUDF, loc, argVar);
+ arg = normalize_fo_arg(i, arg, inlineUDF, loc);
+ arguments.push_back(arg);
}
expr* body =
CREATE(dynamic_function_invocation)(theRootSctx,
theUDF,
loc,
- CREATE(wrapper)(theRootSctx, theUDF, loc, inner_subst_var),
+ CREATE(wrapper)(theRootSctx, theUDF, loc,
+ fiSubstVar),
arguments,
NULL);
- create_inline_function(body,
- inner_flwor,
- func_type->get_param_types(),
- func_type->get_return_type(),
- loc,
- true);
+ if (returnType->isBuiltinAtomicAny())
+ {
+ body = wrap_in_type_promotion(body, returnType, PROMOTE_TYPE_PROMOTION);
+ }
+ else
+ {
+ body = wrap_in_type_match(body, returnType, loc, TREAT_TYPE_MATCH);
+ }
- theExpr = pop_nodestack();
- fnItem_flwor->set_return_expr(theExpr);
- theExpr = fnItem_flwor;
+ inlineUDF->setBody(body);
+ inlineUDF->setScriptingKind(body->get_scripting_detail());
+ inlineUDF->setArgVars(argVars);
+ inlineUDF->setOptimized(true);
// pop the scope.
pop_scope();
- return theExpr;
+ return coersionFlwor;
}
@@ -3984,7 +4002,7 @@
// Wrap in coercion if the return type is a function item
if (returnType->type_kind() == XQType::FUNCTION_TYPE_KIND)
{
- body = wrap_in_coercion(returnType, body, loc, theCCB, true);
+ body = wrap_in_coercion(returnType, body, loc);
}
// If function has any params, they have been wraped in a flwor expr. Set the
@@ -12069,7 +12087,7 @@
}
}
- create_inline_function(body, flwor, paramTypes, returnType, loc, false);
+ create_inline_function(body, flwor, paramTypes, returnType, loc);
// pop the scope.
pop_scope();
@@ -12084,8 +12102,7 @@
flwor_expr* flwor,
const std::vector<xqtref_t>& paramTypes,
xqtref_t returnType,
- const QueryLoc& loc,
- bool is_coercion)
+ const QueryLoc& loc)
{
std::vector<var_expr*> argVars;
@@ -12131,11 +12148,10 @@
// invoked in many other places, it is not possible to perform function
// call normalization. Instead the domain expressions of arg vars is
// wrapped in type matches.
- if (!is_coercion)
- letClause->set_expr(normalize_fo_arg(i,
- letClause->get_expr(),
- udf.getp(),
- loc));
+ letClause->set_expr(normalize_fo_arg(i,
+ letClause->get_expr(),
+ udf.getp(),
+ loc));
}
}
=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt 2013-03-27 09:26:16 +0000
+++ test/fots/CMakeLists.txt 2013-03-27 12:42:22 +0000
@@ -643,7 +643,6 @@
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-528 0)
EXPECTED_FOTS_FAILURE (fn-map-pairs fn-map-pairs-026 0)
EXPECTED_FOTS_FAILURE (misc-HigherOrderFunctions hof-036 0)
-EXPECTED_FOTS_FAILURE (misc-HigherOrderFunctions hof-919 0)
EXPECTED_FOTS_FAILURE (misc-HigherOrderFunctions xqhof12 0)
EXPECTED_FOTS_FAILURE (misc-HigherOrderFunctions xqhof14 0)
EXPECTED_FOTS_FAILURE (misc-HigherOrderFunctions xqhof15 0)
Follow ups