zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #19314
[Merge] lp:~zorba-coders/zorba/hof-merge into lp:zorba
Markos Zaharioudakis has proposed merging lp:~zorba-coders/zorba/hof-merge into lp:zorba.
Commit message:
cleanup + fixed 2 hof tests concerning the fn:fold-right function
Requested reviews:
Markos Zaharioudakis (markos-za)
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/hof-merge/+merge/155100
cleanup + fixed 2 hof tests concerning the fn:fold-right function
--
https://code.launchpad.net/~zorba-coders/zorba/hof-merge/+merge/155100
Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'src/compiler/expression/expr_clone.cpp'
--- src/compiler/expression/expr_clone.cpp 2013-03-21 18:53:47 +0000
+++ src/compiler/expression/expr_clone.cpp 2013-03-23 15:23:24 +0000
@@ -386,7 +386,6 @@
create_function_item_expr(theSctx,
udf,
get_loc(),
- e->theDynamicFunctionInfo->theClosureSctx,
e->theDynamicFunctionInfo->theFunction,
e->theDynamicFunctionInfo->theFunction->getName(),
e->theDynamicFunctionInfo->theArity,
@@ -394,11 +393,20 @@
e->needs_context_item(),
e->is_coercion());
- std::vector<expr*>::const_iterator varIter = e->theDynamicFunctionInfo->theScopedVarsValues.begin();
- std::vector<var_expr*>::const_iterator substVarIter = e->theDynamicFunctionInfo->theSubstVarsValues.begin();
- std::vector<store::Item_t>::const_iterator nameIter = e->theDynamicFunctionInfo->theScopedVarsNames.begin();
- std::vector<int>::const_iterator isGlobalIter = e->theDynamicFunctionInfo->theIsGlobalVar.begin();
- for (; varIter != e->theDynamicFunctionInfo->theScopedVarsValues.end(); ++varIter, ++substVarIter, ++nameIter, ++isGlobalIter)
+ std::vector<expr*>::const_iterator varIter =
+ e->theDynamicFunctionInfo->theScopedVarsValues.begin();
+
+ std::vector<var_expr*>::const_iterator substVarIter =
+ e->theDynamicFunctionInfo->theSubstVarsValues.begin();
+
+ std::vector<store::Item_t>::const_iterator nameIter =
+ e->theDynamicFunctionInfo->theScopedVarsNames.begin();
+
+ std::vector<int>::const_iterator isGlobalIter =
+ e->theDynamicFunctionInfo->theIsGlobalVar.begin();
+
+ for (; varIter != e->theDynamicFunctionInfo->theScopedVarsValues.end();
+ ++varIter, ++substVarIter, ++nameIter, ++isGlobalIter)
{
cloneExpr->add_variable((*varIter) ? (*varIter)->clone(udf, subst) : NULL,
(*substVarIter) ? static_cast<var_expr*>((*substVarIter)->clone(udf, subst)) : NULL,
=== modified file 'src/compiler/expression/expr_manager.cpp'
--- src/compiler/expression/expr_manager.cpp 2013-03-17 13:44:16 +0000
+++ src/compiler/expression/expr_manager.cpp 2013-03-23 15:23:24 +0000
@@ -496,16 +496,6 @@
CREATE_AND_RETURN_EXPR(wrapper_expr, sctx, udf, loc, wrapped);
}
-#if 0
-function_trace_expr* ExprManager::create_function_trace_expr(
- static_context* sctx,
- user_function* udf,
- const QueryLoc& loc,
- expr* aChild)
-{
- CREATE_AND_RETURN_EXPR(function_trace_expr, sctx, udf, loc, aChild);
-}
-#endif
function_trace_expr* ExprManager::create_function_trace_expr(
user_function* udf,
@@ -818,30 +808,32 @@
}
-function_item_expr* ExprManager::create_function_item_expr(static_context* sctx,
+function_item_expr* ExprManager::create_function_item_expr(
+ static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context* closureSctx,
function* f,
- store::Item* aQName,
- uint32_t aArity,
+ store::Item* qname,
+ uint32_t arity,
bool isInline,
bool needsContextItem,
bool isCoercion)
{
- CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc, closureSctx, f, aQName, aArity, isInline, needsContextItem, isCoercion);
+ CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc,
+ f, qname, arity, isInline, needsContextItem, isCoercion);
}
-function_item_expr* ExprManager::create_function_item_expr(static_context* sctx,
+function_item_expr* ExprManager::create_function_item_expr(
+ static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context *closureSctx,
bool isInline,
bool needsContextItem,
bool isCoercion)
{
- CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc, closureSctx, isInline, needsContextItem, isCoercion);
+ CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc,
+ isInline, needsContextItem, isCoercion);
}
=== modified file 'src/compiler/expression/expr_manager.h'
--- src/compiler/expression/expr_manager.h 2013-03-17 13:44:16 +0000
+++ src/compiler/expression/expr_manager.h 2013-03-23 15:23:24 +0000
@@ -306,14 +306,6 @@
const QueryLoc& loc,
expr* wrapped);
-#if 0
- function_trace_expr* create_function_trace_expr(
- static_context* sctx,
- user_function* udf,
- const QueryLoc& loc,
- expr* aChild);
-#endif
-
function_trace_expr* create_function_trace_expr(
user_function* udf,
expr* aExpr);
@@ -500,10 +492,9 @@
function_item_expr* create_function_item_expr(static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context *closureSctx,
function* f,
- store::Item* aQName,
- uint32_t aArity,
+ store::Item* qname,
+ uint32_t arity,
bool isInline,
bool needsContextItem,
bool isCoercion);
@@ -512,7 +503,6 @@
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context *closureSctx,
bool isInline,
bool needsContextItem,
bool isCoercion);
=== modified file 'src/compiler/expression/function_item_expr.cpp'
--- src/compiler/expression/function_item_expr.cpp 2013-03-17 13:55:28 +0000
+++ src/compiler/expression/function_item_expr.cpp 2013-03-23 15:23:24 +0000
@@ -29,7 +29,9 @@
namespace zorba {
-DEF_EXPR_ACCEPT (dynamic_function_invocation_expr);
+/*******************************************************************************
+
+********************************************************************************/
dynamic_function_invocation_expr::dynamic_function_invocation_expr(
@@ -61,47 +63,47 @@
}
+DEF_EXPR_ACCEPT(dynamic_function_invocation_expr);
+
+
/*******************************************************************************
********************************************************************************/
+void argument_placeholder_expr::compute_scripting_kind()
+{
+ theScriptingKind = SIMPLE_EXPR;
+}
+
+
DEF_EXPR_ACCEPT (argument_placeholder_expr);
-void argument_placeholder_expr::compute_scripting_kind()
-{
- theScriptingKind = SIMPLE_EXPR;
-}
-
/*******************************************************************************
********************************************************************************/
-DEF_EXPR_ACCEPT (function_item_expr);
-
function_item_expr::function_item_expr(CompilerCB* ccb,
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context* closureSctx,
function* f,
- store::Item* aQName,
- uint32_t aArity,
+ store::Item* qname,
+ uint32_t arity,
bool isInline,
bool needsContextItem,
bool isCoercion)
:
expr(ccb, sctx, udf, loc, function_item_expr_kind),
- theDynamicFunctionInfo(new DynamicFunctionInfo(
- closureSctx,
- loc,
- f,
- aQName,
- aArity,
- isInline,
- needsContextItem,
- isCoercion))
+ theDynamicFunctionInfo(new DynamicFunctionInfo(sctx,
+ loc,
+ f,
+ qname,
+ arity,
+ isInline,
+ needsContextItem,
+ isCoercion))
{
assert(f != NULL);
compute_scripting_kind();
@@ -112,21 +114,19 @@
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context* closureSctx,
bool isInline,
bool needsContextItem,
bool isCoercion)
:
expr(ccb, sctx, udf, loc, function_item_expr_kind),
- theDynamicFunctionInfo(new DynamicFunctionInfo(
- closureSctx,
- loc,
- NULL,
- NULL,
- 0,
- isInline,
- needsContextItem,
- isCoercion))
+ theDynamicFunctionInfo(new DynamicFunctionInfo(sctx,
+ loc,
+ NULL,
+ NULL,
+ 0,
+ isInline,
+ needsContextItem,
+ isCoercion))
{
theScriptingKind = SIMPLE_EXPR;
}
@@ -136,7 +136,12 @@
{
}
-void function_item_expr::add_variable(expr* var, var_expr* substVar, const store::Item_t& name, int isGlobal)
+
+void function_item_expr::add_variable(
+ expr* var,
+ var_expr* substVar,
+ const store::Item_t& name,
+ int isGlobal)
{
theDynamicFunctionInfo->add_variable(var, substVar, name, isGlobal);
}
@@ -157,6 +162,7 @@
theScriptingKind = SIMPLE_EXPR;
}
+
store::Item_t function_item_expr::create_inline_fname(const QueryLoc& loc)
{
store::Item_t name;
@@ -169,5 +175,8 @@
}
+DEF_EXPR_ACCEPT (function_item_expr);
+
+
}//end of namespace
/* vim:set et sw=2 ts=2: */
=== modified file 'src/compiler/expression/function_item_expr.h'
--- src/compiler/expression/function_item_expr.h 2013-03-17 13:44:16 +0000
+++ src/compiler/expression/function_item_expr.h 2013-03-23 15:23:24 +0000
@@ -85,7 +85,8 @@
expr * theDotVar;
protected:
- dynamic_function_invocation_expr(CompilerCB* ccb,
+ dynamic_function_invocation_expr(
+ CompilerCB* ccb,
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
@@ -116,24 +117,6 @@
InlineFunction ::= "function" "(" ParamList? ")" ("as" SequenceType)? EnclosedExpr
- theFunction :
- This is always a pointer to a user_function obj. In case of an inline function
- expr, it is an anonymous user_function obj that is created on-the-fly by the
- translator to represent the body and signature of the inline function. In case
- of LiteralFunctionItem where the named function is a UDF, it is the
- user_function obj of that UDF. Finally, in case of LiteralFunctionItem where
- the named function F is not a UDF, it is an anonymous user_function obj UF
- that is created on-the-fly by the translator. The signature of UF is the same
- as that of F, and its body simply invokes F. The reason why UF is built is to
- unify the implemenation of dynamic function invocation.
-
- theArity :
- We need to store the arity also here because the function above doesn't know
- about its arity in case it's a variadic function.
-
- theScopedVariables :
- Empty in the case of LiteralFunctionItem. Otherwise, the FLWOR vars that are
- in scope at the place where the InlineFunction expr appears at.
********************************************************************************/
class function_item_expr: public expr
{
@@ -150,7 +133,6 @@
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context* closureSctx,
function* f,
store::Item* aQName,
uint32_t aArity,
@@ -163,7 +145,6 @@
static_context* sctx,
user_function* udf,
const QueryLoc& loc,
- static_context* closureSctx,
bool isInline,
bool needsContextItem,
bool isCoercion);
=== modified file 'src/compiler/translator/translator.cpp'
--- src/compiler/translator/translator.cpp 2013-03-20 23:33:11 +0000
+++ src/compiler/translator/translator.cpp 2013-03-23 15:23:24 +0000
@@ -1378,6 +1378,165 @@
}
+
+/*******************************************************************************
+
+********************************************************************************/
+void normalize_fo(fo_expr* foExpr)
+{
+ const QueryLoc& loc = foExpr->get_loc();
+
+ csize n = foExpr->num_args();
+
+ const function* func = foExpr->get_func();
+ FunctionConsts::FunctionKind fkind = func->getKind();
+
+ if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
+ fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
+ {
+ csize nStarterParams =
+ (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ? 1 : 2);
+
+ if (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
+ {
+ const store::Item* qname = NULL;
+
+ if (n > 0)
+ qname = foExpr->get_arg(0)->getQName();
+
+ zstring lMsgPart;
+ ztd::to_string(nStarterParams, &lMsgPart);
+ lMsgPart += " + multiple of 6";
+ if (qname != NULL)
+ {
+ RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
+ ERROR_PARAMS(qname->getStringValue(), "index", n, lMsgPart));
+ }
+ else
+ {
+ RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
+ ERROR_PARAMS("anonymous", "index", n, lMsgPart));
+ }
+ }
+ }
+
+ for (csize i = 0; i < n; ++i)
+ {
+ expr* argExpr = foExpr->get_arg(i);
+
+ argExpr = normalize_fo_arg(i, argExpr, func, loc);
+
+ foExpr->set_arg(i, argExpr);
+ }
+}
+
+
+/*******************************************************************************
+
+********************************************************************************/
+expr* normalize_fo_arg(
+ csize i,
+ expr* argExpr,
+ const function* func,
+ const QueryLoc& loc)
+{
+ xqtref_t paramType;
+
+ const signature& sign = func->getSignature();
+
+ TypeManager* tm = argExpr->get_type_manager();
+
+ switch (func->getKind())
+ {
+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N:
+ {
+ if (i == 0)
+ paramType = sign[i];
+ else
+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
+
+ break;
+ }
+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N:
+ {
+ if (i <= 1)
+ paramType = sign[i];
+ else
+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
+
+ break;
+ }
+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N:
+ {
+ if (i == 0)
+ paramType = sign[i];
+ else if (i % 6 == 1 || i % 6 == 2)
+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
+ else
+ paramType = theRTM.BOOLEAN_TYPE_ONE;
+
+ break;
+ }
+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N:
+ {
+ if (i <= 1)
+ paramType = sign[i];
+ else if (i % 6 == 2 || i % 6 == 3)
+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
+ else
+ paramType = theRTM.BOOLEAN_TYPE_ONE;
+
+ break;
+ }
+ case FunctionConsts::FN_ZORBA_INVOKE_N:
+ case FunctionConsts::FN_ZORBA_INVOKE_N_N:
+ case FunctionConsts::FN_ZORBA_INVOKE_U_N:
+ case FunctionConsts::FN_ZORBA_INVOKE_S_N:
+ {
+ if (i == 0)
+ paramType = sign[i];
+ else
+ paramType = NULL; // Nothing to check as the target function is not known
+
+ break;
+ }
+ default:
+ {
+ paramType = sign[i];
+ }
+ }
+
+ // A NULL value for the parameter's type to signal that no type promotion
+ // or match should be added. This is used by the reflection:invoke() function,
+ if (paramType != NULL)
+ {
+ if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
+ {
+ argExpr = wrap_in_type_promotion(argExpr,
+ paramType,
+ PROMOTE_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,
+ TREAT_FUNC_PARAM,
+ func->getName());
+ }
+ }
+
+ return argExpr;
+}
+
+
/*******************************************************************************
********************************************************************************/
@@ -1392,15 +1551,15 @@
// Create the dynamic call body
- static_context* closureSctx = theRootSctx->create_child_context();
- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
- function_item_expr* fiExpr = theExprManager->create_function_item_expr(theRootSctx, theUDF, loc, closureSctx, true, false, true /* isCoercion */);
+ function_item_expr* fiExpr =
+ CREATE(function_item)(theRootSctx, theUDF, loc, true, false, true);
+
push_nodestack(fiExpr);
push_scope();
// handle the function item expression
- flwor_expr* fnItem_flwor = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
+ 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);
@@ -1408,13 +1567,13 @@
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 = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
+ flwor_expr* inner_flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
var_expr* inner_arg_var = create_var(loc, fnItem_var->get_name(), var_expr::let_var);
inner_arg_var->set_param_pos(inner_flwor->num_clauses());
// Handle parameters. For each parameter, a let binding is added to the inner flwor.
std::vector<expr*> arguments; // Arguments to the dynamic function call
- for(unsigned i = 0; i<func_type->get_number_params(); i++)
+ for(csize i = 0; i < func_type->get_number_params(); i++)
{
xqtref_t paramType = func_type->operator[](i);
@@ -1427,7 +1586,7 @@
inner_flwor->add_clause(lc);
- arguments.push_back(theExprManager->create_wrapper_expr(theRootSctx, theUDF, loc, subst_var));
+ arguments.push_back(CREATE(wrapper)(theRootSctx, theUDF, loc, subst_var));
}
if (inner_flwor->num_clauses() == 0)
@@ -1435,13 +1594,13 @@
inner_flwor = NULL;
}
- expr* body = CREATE(dynamic_function_invocation)(
- theRootSctx,
- theUDF,
- loc,
- CREATE(wrapper)(theRootSctx, theUDF, loc, inner_subst_var),
- arguments,
- NULL);
+ expr* body =
+ CREATE(dynamic_function_invocation)(theRootSctx,
+ theUDF,
+ loc,
+ CREATE(wrapper)(theRootSctx, theUDF, loc, inner_subst_var),
+ arguments,
+ NULL);
create_inline_function(body,
inner_flwor,
@@ -1462,164 +1621,6 @@
/*******************************************************************************
-
-********************************************************************************/
-expr* normalize_fo_arg(
- csize i,
- expr* argExpr,
- const function* func,
- const QueryLoc& loc)
-{
- xqtref_t paramType;
-
- const signature& sign = func->getSignature();
-
- TypeManager* tm = argExpr->get_type_manager();
-
- switch (func->getKind())
- {
- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N:
- {
- if (i == 0)
- paramType = sign[i];
- else
- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
-
- break;
- }
- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N:
- {
- if (i <= 1)
- paramType = sign[i];
- else
- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
-
- break;
- }
- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N:
- {
- if (i == 0)
- paramType = sign[i];
- else if (i % 6 == 1 || i % 6 == 2)
- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
- else
- paramType = theRTM.BOOLEAN_TYPE_ONE;
-
- break;
- }
- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N:
- {
- if (i <= 1)
- paramType = sign[i];
- else if (i % 6 == 2 || i % 6 == 3)
- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
- else
- paramType = theRTM.BOOLEAN_TYPE_ONE;
-
- break;
- }
- case FunctionConsts::FN_ZORBA_INVOKE_N:
- case FunctionConsts::FN_ZORBA_INVOKE_N_N:
- case FunctionConsts::FN_ZORBA_INVOKE_U_N:
- case FunctionConsts::FN_ZORBA_INVOKE_S_N:
- {
- if (i == 0)
- paramType = sign[i];
- else
- paramType = NULL; // Nothing to check as the target function is not known
-
- break;
- }
- default:
- {
- paramType = sign[i];
- }
- }
-
- // A NULL value for the parameter's type to signal that no type promotion
- // or match should be added. This is used by the reflection:invoke() function,
- if (paramType != NULL)
- {
- if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
- {
- argExpr = wrap_in_type_promotion(argExpr,
- paramType,
- PROMOTE_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,
- TREAT_FUNC_PARAM,
- func->getName());
- }
- }
-
- return argExpr;
-}
-
-
-/*******************************************************************************
-
-********************************************************************************/
-void normalize_fo(fo_expr* foExpr)
-{
- const QueryLoc& loc = foExpr->get_loc();
-
- csize n = foExpr->num_args();
-
- const function* func = foExpr->get_func();
- FunctionConsts::FunctionKind fkind = func->getKind();
-
- if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
- fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
- {
- csize nStarterParams =
- (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ? 1 : 2);
-
- if (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
- {
- const store::Item* qname = NULL;
-
- if (n > 0)
- qname = foExpr->get_arg(0)->getQName();
-
- zstring lMsgPart;
- ztd::to_string(nStarterParams, &lMsgPart);
- lMsgPart += " + multiple of 6";
- if (qname != NULL)
- {
- RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
- ERROR_PARAMS(qname->getStringValue(), "index", n, lMsgPart));
- }
- else
- {
- RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
- ERROR_PARAMS("anonymous", "index", n, lMsgPart));
- }
- }
- }
-
- for (csize i = 0; i < n; ++i)
- {
- expr* argExpr = foExpr->get_arg(i);
-
- argExpr = normalize_fo_arg(i, argExpr, func, loc);
-
- foExpr->set_arg(i, argExpr);
- }
-}
-
-
-/*******************************************************************************
Wrap the given expr in an fn:data() function
********************************************************************************/
expr* wrap_in_atomization(expr* e)
@@ -10911,6 +10912,8 @@
arguments.push_back(argExpr);
}
+ std::reverse(arguments.begin(), arguments.end());
+
csize numArgs = arguments.size();
// Lookup the function
@@ -10936,12 +10939,8 @@
const QueryLoc& loc)
{
TypeManager* tm = CTX_TM;
-
- expr* resultExpr = NULL;
-
store::Item_t qnameItem;
zstring fn_ns;
-
csize numArgs = arguments.size();
if (f == NULL)
@@ -10995,21 +10994,11 @@
ERROR_PARAMS(fn_ns));
}
- // Add context-item for functions with zero arguments which implicitly
- // take the context-item as argument
- if (xquery_fns_def_dot.test(f->getKind()))
- {
- arguments.push_back(DOT_REF);
- f = theSctx->lookup_fn(qnameItem, 1, loc);
- }
-
// Check if it is a zorba builtin function, and if so,
// make sure that the module it belongs to has been imported.
if (f->isBuiltin() &&
fn_ns != static_context::W3C_FN_NS &&
-#ifdef ZORBA_WITH_JSON
fn_ns != static_context::JSONIQ_FN_NS &&
-#endif
fn_ns != XQUERY_MATH_FN_NS &&
fn_ns != theModuleNamespace)
{
@@ -11020,168 +11009,16 @@
}
}
- // Special processing for certain builtin functions
- switch (f->getKind())
- {
- case FunctionConsts::FN_HEAD_1:
- case FunctionConsts::FN_TAIL_1:
- case FunctionConsts::FN_NUMBER_1:
- case FunctionConsts::FN_POSITION_0:
- case FunctionConsts::FN_LAST_0:
- case FunctionConsts::FN_STATIC_BASE_URI_0:
- case FunctionConsts::FN_APPLY_1:
- {
- resultExpr = generate_fn_body(f, arguments, loc);
- break;
- }
- case FunctionConsts::FN_IDREF_1:
- {
- arguments.insert(arguments.begin(), DOT_REF);
- f = BUILTIN_FUNC(FN_IDREF_2);
- break;
- }
- case FunctionConsts::FN_LANG_1:
- {
- arguments.insert(arguments.begin(), DOT_REF);
- f = BUILTIN_FUNC(FN_LANG_2);
- break;
- }
- case FunctionConsts::FN_RESOLVE_URI_1:
- {
- zstring baseUri = theSctx->get_base_uri();
- arguments.insert(arguments.begin(),
- CREATE(const)(theRootSctx, theUDF, loc, baseUri));
- f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
- break;
- }
- case FunctionConsts::FN_SUBSEQUENCE_2:
- case FunctionConsts::FN_SUBSEQUENCE_3:
- case FunctionConsts::FN_SUBSTRING_2:
- case FunctionConsts::FN_SUBSTRING_3:
- {
- if (numArgs == 2)
- {
- xqtref_t posType = arguments[0]->get_return_type();
-
- if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc))
- {
- if (f->getKind() == FunctionConsts::FN_SUBSTRING_2)
- f = BUILTIN_FUNC(OP_SUBSTRING_INT_2);
- else
- f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_2);
- }
- }
- else
- {
- xqtref_t posType = arguments[1]->get_return_type();
- xqtref_t lenType = arguments[0]->get_return_type();
-
- if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc) &&
- TypeOps::is_subtype(tm, *lenType, *theRTM.INTEGER_TYPE_STAR, loc))
- {
- if (f->getKind() == FunctionConsts::FN_SUBSTRING_3)
- f = BUILTIN_FUNC(OP_SUBSTRING_INT_3);
- else
- f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_3);
- }
- }
-
- break;
- }
- case FunctionConsts::FN_ID_1:
- case FunctionConsts::FN_ID_2:
- case FunctionConsts::FN_ELEMENT_WITH_ID_1:
- case FunctionConsts::FN_ELEMENT_WITH_ID_2:
- {
- if (numArgs == 1)
- {
- arguments.insert(arguments.begin(), DOT_REF);
- f = theSctx->lookup_fn(qnameItem, 2, loc);
- }
-
- expr* idsExpr = arguments[1];
-
- flwor_expr* flworExpr = wrap_expr_in_flwor(idsExpr, false);
-
- const for_clause* fc = static_cast<const for_clause*>(flworExpr->get_clause(0));
- expr* flworVarExpr = fc->get_var();
-
- fo_expr* normExpr = NULL;
- fo_expr* tokenExpr = NULL;
- zstring space(" ");
- const_expr* constExpr = CREATE(const)(theRootSctx, theUDF, loc, space);
-
- normExpr = CREATE(fo)(theRootSctx, theUDF, loc,
- BUILTIN_FUNC(FN_NORMALIZE_SPACE_1),
- flworVarExpr);
- normalize_fo(normExpr);
-
- tokenExpr = CREATE(fo)(theRootSctx, theUDF, loc,
- BUILTIN_FUNC(FN_TOKENIZE_2),
- normExpr,
- constExpr);
- normalize_fo(tokenExpr);
-
- flworExpr->set_return_expr(tokenExpr);
-
- pop_scope();
-
- arguments[1] = flworExpr;
- break;
- }
- case FunctionConsts::FN_FOLD_RIGHT_3:
- {
- // Because arguments are reversed, the 3rd argument is actually arguments[0]
- arguments[0] = CREATE(fo)(theRootSctx, theUDF, loc,
- BUILTIN_FUNC(FN_REVERSE_1),
- arguments[0]);
- break;
- }
- case FunctionConsts::FN_CONCAT_N:
- {
- if (numArgs < 2)
- {
- RAISE_ERROR(err::XPST0017, loc,
- ERROR_PARAMS("concat", ZED(FunctionUndeclared_3), numArgs));
- }
- break;
- }
- case FunctionConsts::FN_DOC_1:
- {
- expr* doc_uri = arguments[0];
-
- //validate uri
- if (doc_uri->get_expr_kind() == const_expr_kind)
- {
- const_expr* const_uri = reinterpret_cast<const_expr*>(doc_uri);
- const store::Item* uri_value = const_uri->get_val();
- zstring uri_string = uri_value->getStringValue();
-
- try
- {
- if (uri_string.find(":/", 0, 3) != zstring::npos)
- {
- URI docURI(uri_string, true);//with validate
- }
- }
- catch(XQueryException& e)
- {
- set_source(e, loc);
- throw;
- }
- }
- break;
- }
- default:
- {
- }
- }
-
- if (resultExpr)
- {
- f->processPragma(resultExpr, theScopedPragmas);
- return resultExpr;
- }
+ // Add context-item for functions with zero arguments which implicitly
+ // take the context-item as argument
+ if (xquery_fns_def_dot.test(f->getKind()))
+ {
+ assert(arguments.empty());
+ arguments.push_back(DOT_REF);
+ f = theSctx->lookup_fn(qnameItem, 1, loc);
+ }
+
+ expr* resultExpr = generate_fn_body(f, arguments, loc);
numArgs = arguments.size(); // recompute size
@@ -11198,20 +11035,12 @@
}
}
- // Create and normalize the fo expr
- std::reverse(arguments.begin(), arguments.end());
-
- fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
- normalize_fo(foExpr);
-
- resultExpr = foExpr;
-
if (f->isExternal())
{
const xqtref_t& resType = f->getSignature().returnType();
resultExpr =
- wrap_in_type_match(foExpr, resType, loc, TREAT_FUNC_RETURN, f->getName());
+ wrap_in_type_match(resultExpr, resType, loc, TREAT_FUNC_RETURN, f->getName());
}
// Some further normalization is required for certain builtin functions
@@ -11221,9 +11050,9 @@
case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N:
case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_GENERAL_N:
{
- resultExpr = CREATE(fo)(theRootSctx, theUDF, foExpr->get_loc(),
+ resultExpr = CREATE(fo)(theRootSctx, theUDF, resultExpr->get_loc(),
BUILTIN_FUNC(OP_SORT_DISTINCT_NODES_ASC_1),
- foExpr);
+ resultExpr);
break;
}
@@ -11231,7 +11060,7 @@
case FunctionConsts::FN_ANALYZE_STRING_3:
{
resultExpr =
- wrap_in_validate_expr_strict(foExpr, "http://www.w3.org/2005/xpath-functions";);
+ wrap_in_validate_expr_strict(resultExpr, "http://www.w3.org/2005/xpath-functions";);
break;
}
@@ -11243,50 +11072,6 @@
break;
}
- case FunctionConsts::FN_MAP_2:
- case FunctionConsts::FN_FILTER_2:
- {
- std::vector<expr*> args(foExpr->get_args());
- resultExpr = generate_fn_body(f, args, loc);
- break;
- }
- case FunctionConsts::FN_ZORBA_EVAL_1:
- case FunctionConsts::FN_ZORBA_EVAL_N_1:
- case FunctionConsts::FN_ZORBA_EVAL_U_1:
- case FunctionConsts::FN_ZORBA_EVAL_S_1:
- {
- expr_script_kind_t scriptKind;
-
- if (fKind == FunctionConsts::FN_ZORBA_EVAL_1 ||
- fKind == FunctionConsts::FN_ZORBA_EVAL_N_1)
- {
- scriptKind = SIMPLE_EXPR;
- }
- else if (fKind == FunctionConsts::FN_ZORBA_EVAL_U_1)
- {
- scriptKind = UPDATING_EXPR;
- }
- else
- {
- scriptKind = SEQUENTIAL_FUNC_EXPR;
- }
-
- eval_expr* evalExpr =
- CREATE(eval)(theRootSctx, theUDF, loc, foExpr->get_arg(0), scriptKind, theNSCtx);
-
- std::vector<VarInfo*> inscopeVars;
- theSctx->getVariables(inscopeVars);
-
- csize numVars = inscopeVars.size();
-
- for (csize i = 0; i < numVars; ++i)
- {
- evalExpr->add_var(inscopeVars[i]->getVar());
- }
-
- resultExpr = evalExpr;
- break;
- }
case FunctionConsts::FN_ZORBA_INVOKE_N:
case FunctionConsts::FN_ZORBA_INVOKE_N_N:
case FunctionConsts::FN_ZORBA_INVOKE_U_N:
@@ -11446,9 +11231,15 @@
std::vector<expr*>& arguments,
const QueryLoc& loc)
{
+ TypeManager* tm = CTX_TM;
+
expr* resultExpr = NULL;
- switch (f->getKind())
+ csize numArgs = arguments.size();
+
+ FunctionConsts::FunctionKind fkind = f->getKind();
+
+ switch (fkind)
{
case FunctionConsts::FN_POSITION_0:
{
@@ -11460,6 +11251,66 @@
resultExpr = lookup_ctx_var(LAST_IDX_VARNAME, loc);
break;
}
+ case FunctionConsts::FN_LANG_1:
+ {
+ arguments.push_back(DOT_REF);
+ f = BUILTIN_FUNC(FN_LANG_2);
+ break;
+ }
+ case FunctionConsts::FN_IDREF_1:
+ {
+ arguments.push_back(DOT_REF);
+ f = BUILTIN_FUNC(FN_IDREF_2);
+ break;
+ }
+ case FunctionConsts::FN_ID_1:
+ {
+ arguments.push_back(DOT_REF);
+ f = BUILTIN_FUNC(FN_ID_2);
+ resultExpr = generate_fn_body(f, arguments, loc);
+ break;
+ }
+ case FunctionConsts::FN_ELEMENT_WITH_ID_1:
+ {
+ arguments.push_back(DOT_REF);
+ f = BUILTIN_FUNC(FN_ELEMENT_WITH_ID_2);
+ resultExpr = generate_fn_body(f, arguments, loc);
+ break;
+ }
+ case FunctionConsts::FN_ID_2:
+ case FunctionConsts::FN_ELEMENT_WITH_ID_2:
+ {
+ expr* idsExpr = arguments[0];
+
+ flwor_expr* flworExpr = wrap_expr_in_flwor(idsExpr, false);
+
+ const for_clause* fc = static_cast<const for_clause*>(flworExpr->get_clause(0));
+ expr* flworVarExpr = fc->get_var();
+
+ fo_expr* normExpr = NULL;
+ fo_expr* tokenExpr = NULL;
+ zstring space(" ");
+ const_expr* constExpr = CREATE(const)(theRootSctx, theUDF, loc, space);
+
+ normExpr = CREATE(fo)(theRootSctx, theUDF, loc,
+ BUILTIN_FUNC(FN_NORMALIZE_SPACE_1),
+ flworVarExpr);
+ normalize_fo(normExpr);
+
+ tokenExpr = CREATE(fo)(theRootSctx, theUDF, loc,
+ BUILTIN_FUNC(FN_TOKENIZE_2),
+ normExpr,
+ constExpr);
+ normalize_fo(tokenExpr);
+
+ flworExpr->set_return_expr(tokenExpr);
+
+ pop_scope();
+
+ arguments[0] = flworExpr;
+
+ break;
+ }
case FunctionConsts::FN_HEAD_1:
{
arguments.push_back(CREATE(const)(theRootSctx, theUDF, loc, xs_integer::one()));
@@ -11487,6 +11338,10 @@
}
case FunctionConsts::FN_NUMBER_1:
{
+ // fn:number($arg) is translated as:
+ //
+ // let $v := data($arg) promote as xs:anyAtomicType?
+ // return if ($v castable as xs:double) then xs:double($v) else NaN
var_expr* tv = create_temp_var(loc, var_expr::let_var);
expr* nanExpr = CREATE(const)(theRootSctx, theUDF, loc, xs_double::nan());
@@ -11520,6 +11375,133 @@
theRTM.ANY_URI_TYPE_ONE, false);
break;
}
+ case FunctionConsts::FN_RESOLVE_URI_1:
+ {
+ zstring baseUri = theSctx->get_base_uri();
+ arguments.push_back(CREATE(const)(theRootSctx, theUDF, loc, baseUri));
+ f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
+
+ fo_expr* fo = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
+ normalize_fo(fo);
+ resultExpr = fo;
+
+ break;
+ }
+ case FunctionConsts::FN_SUBSEQUENCE_2:
+ case FunctionConsts::FN_SUBSEQUENCE_3:
+ case FunctionConsts::FN_SUBSTRING_2:
+ case FunctionConsts::FN_SUBSTRING_3:
+ {
+ if (numArgs == 2)
+ {
+ xqtref_t posType = arguments[1]->get_return_type();
+
+ if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc))
+ {
+ if (f->getKind() == FunctionConsts::FN_SUBSTRING_2)
+ f = BUILTIN_FUNC(OP_SUBSTRING_INT_2);
+ else
+ f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_2);
+ }
+ }
+ else
+ {
+ xqtref_t posType = arguments[1]->get_return_type();
+ xqtref_t lenType = arguments[2]->get_return_type();
+
+ if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc) &&
+ TypeOps::is_subtype(tm, *lenType, *theRTM.INTEGER_TYPE_STAR, loc))
+ {
+ if (f->getKind() == FunctionConsts::FN_SUBSTRING_3)
+ f = BUILTIN_FUNC(OP_SUBSTRING_INT_3);
+ else
+ f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_3);
+ }
+ }
+
+ break;
+ }
+ case FunctionConsts::FN_CONCAT_N:
+ {
+ if (numArgs < 2)
+ {
+ RAISE_ERROR(err::XPST0017, loc,
+ ERROR_PARAMS("concat", ZED(FunctionUndeclared_3), numArgs));
+ }
+ break;
+ }
+ case FunctionConsts::FN_DOC_1:
+ {
+ //validate uri, if known
+ expr* doc_uri = arguments[0];
+
+ if (doc_uri->get_expr_kind() == const_expr_kind)
+ {
+ const_expr* const_uri = reinterpret_cast<const_expr*>(doc_uri);
+ const store::Item* uri_value = const_uri->get_val();
+ zstring uri_string = uri_value->getStringValue();
+
+ try
+ {
+ if (uri_string.find(":/", 0, 3) != zstring::npos)
+ {
+ URI docURI(uri_string, true);//with validate
+ }
+ }
+ catch(XQueryException& e)
+ {
+ set_source(e, loc);
+ throw;
+ }
+ }
+ break;
+ }
+ case FunctionConsts::FN_ZORBA_EVAL_1:
+ case FunctionConsts::FN_ZORBA_EVAL_N_1:
+ case FunctionConsts::FN_ZORBA_EVAL_U_1:
+ case FunctionConsts::FN_ZORBA_EVAL_S_1:
+ {
+ expr_script_kind_t scriptKind;
+
+ if (fkind == FunctionConsts::FN_ZORBA_EVAL_1 ||
+ fkind == FunctionConsts::FN_ZORBA_EVAL_N_1)
+ {
+ scriptKind = SIMPLE_EXPR;
+ }
+ else if (fkind == FunctionConsts::FN_ZORBA_EVAL_U_1)
+ {
+ scriptKind = UPDATING_EXPR;
+ }
+ else
+ {
+ scriptKind = SEQUENTIAL_FUNC_EXPR;
+ }
+
+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
+
+ eval_expr* evalExpr =
+ CREATE(eval)(theRootSctx, theUDF, loc, arguments[0], scriptKind, theNSCtx);
+
+ std::vector<VarInfo*> inscopeVars;
+ theSctx->getVariables(inscopeVars);
+
+ csize numVars = inscopeVars.size();
+
+ for (csize i = 0; i < numVars; ++i)
+ {
+ evalExpr->add_var(inscopeVars[i]->getVar());
+ }
+
+ resultExpr = evalExpr;
+ break;
+ }
+ case FunctionConsts::FN_FOLD_RIGHT_3:
+ {
+ arguments[2] = CREATE(fo)(theRootSctx, theUDF, loc,
+ BUILTIN_FUNC(FN_REVERSE_1),
+ arguments[2]);
+ break;
+ }
case FunctionConsts::FN_MAP_2:
{
// map(function, sequence) is rewritten internally as:
@@ -11527,6 +11509,8 @@
// for $item in $sequence
// return dynamic_function_invocation[ $function, $item ]
+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
+
flwor_expr* flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
for_clause* seq_fc = wrap_in_forclause(arguments[1], false);
flwor->add_clause(seq_fc);
@@ -11555,6 +11539,8 @@
// then $item
// else ()
+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
+
flwor_expr* flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
for_clause* seq_fc = wrap_in_forclause(arguments[1], true);
flwor->add_clause(seq_fc);
@@ -11586,10 +11572,18 @@
}
default:
{
- ZORBA_ASSERT(false);
+ break;
}
} // switch (lKind)
+ if (resultExpr == NULL)
+ {
+ fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
+ normalize_fo(foExpr);
+
+ resultExpr = foExpr;
+ }
+
return resultExpr;
}
@@ -11791,6 +11785,7 @@
{
xqtref_t type;
user_function* udf = NULL;
+ expr* body;
bool needs_context_item = false;
// Get function implementation
@@ -11800,14 +11795,13 @@
// function
if (f == NULL)
{
- type = CTX_TM->create_named_type(qnameItem,
- TypeConstants::QUANT_QUESTION,
- loc);
+ type = CTX_TM->
+ create_named_type(qnameItem, TypeConstants::QUANT_QUESTION, loc);
if (type == NULL ||
arity != 1 ||
- TypeOps::is_equal(CTX_TM, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
- TypeOps::is_equal(CTX_TM, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
+ TypeOps::is_equal(CTX_TM, *type, *theRTM.NOTATION_TYPE_QUESTION, loc) ||
+ TypeOps::is_equal(CTX_TM, *type, *theRTM.ANY_ATOMIC_TYPE_QUESTION, loc))
{
RAISE_ERROR(err::XPST0017, loc,
ERROR_PARAMS(qnameItem->getStringValue(), ZED(FunctionUndeclared_3), arity));
@@ -11826,7 +11820,6 @@
theCCB);
udf->setArgVars(udfArgs);
- udf->setOptimized(true);
f = udf;
}
else
@@ -11870,19 +11863,19 @@
// in a udf UF: function UF(x1 as T1, ..., xN as TN) as R { F(x1, ... xN) }
if (!f->isUdf())
{
- FunctionConsts::FunctionKind fKind = f->getKind();
+ FunctionConsts::FunctionKind fkind = f->getKind();
- // Add context-item for functions with zero arguments which implicitly
- // take the context-item as argument
- if (xquery_fns_def_dot.test(fKind) ||
- fKind == FunctionConsts::FN_LANG_1 ||
- fKind == FunctionConsts::FN_ID_1 ||
- fKind == FunctionConsts::FN_ELEMENT_WITH_ID_1 ||
- fKind == FunctionConsts::FN_IDREF_1)
+ // Add context-item for functions which implicitly access the context-item
+ if (xquery_fns_def_dot.test(fkind) ||
+ fkind == FunctionConsts::FN_LANG_1 ||
+ fkind == FunctionConsts::FN_IDREF_1 ||
+ fkind == FunctionConsts::FN_ID_1 ||
+ fkind == FunctionConsts::FN_ELEMENT_WITH_ID_1)
{
arity++;
f = theSctx->lookup_fn(qnameItem, arity, loc);
needs_context_item = true;
+ fkind = f->getKind();
}
udf = new user_function(loc,
@@ -11902,47 +11895,21 @@
foArgs[i] = argVar;
}
- expr* body;
+ switch (fkind)
+ {
// process pure builtin functions that have no associated iterator
- switch (f->getKind())
- {
- case FunctionConsts::FN_NUMBER_1:
case FunctionConsts::FN_HEAD_1:
case FunctionConsts::FN_TAIL_1:
+ case FunctionConsts::FN_NUMBER_1:
+ case FunctionConsts::FN_STATIC_BASE_URI_0:
+ case FunctionConsts::FN_RESOLVE_URI_1:
+ case FunctionConsts::FN_ID_2:
+ case FunctionConsts::FN_ELEMENT_WITH_ID_2:
+ case FunctionConsts::FN_FOLD_RIGHT_3:
case FunctionConsts::FN_MAP_2:
case FunctionConsts::FN_FILTER_2:
- case FunctionConsts::FN_STATIC_BASE_URI_0:
- {
- // create the function flwor, wrap params in for clauses
- flwor_expr* flwor = CREATE(flwor)(theSctx, theUDF, loc, false);
- std::vector<expr*> arguments;
- for (csize i = 0; i < foArgs.size(); i++)
- {
- let_clause* lc = wrap_in_letclause(&*udfArgs[i]); // FN_HEAD and FN_TAIL need this to be a LET clause
- udfArgs[i]->set_param_pos(flwor->num_clauses());
- flwor->add_clause(lc);
- arguments.push_back(lc->get_var());
- }
-
- flwor->set_return_expr(generate_fn_body(f, arguments, loc));
-
- body = flwor;
-
- if (flwor->num_clauses() == 0)
- body = flwor->get_return_expr();
-
- break;
- }
- case FunctionConsts::FN_RESOLVE_URI_1:
- {
- zstring baseUri = theSctx->get_base_uri();
- foArgs.push_back(CREATE(const)(theRootSctx, theUDF, loc, baseUri));
- f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
-
- fo_expr* fo = CREATE(fo)(theRootSctx, udf, loc, f, foArgs);
- normalize_fo(fo);
-
- body = fo;
+ {
+ body = generate_fn_body(f, foArgs, loc);
break;
}
default:
@@ -11957,23 +11924,18 @@
udf->setArgVars(udfArgs);
udf->setBody(body);
- udf->setOptimized(true); // TODO: this is needed because otherwise the optimizer would get into an infinte cycle
f = udf;
} // if builtin function
}
- static_context* closureSctx = theRootSctx->create_child_context();
- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
-
expr* fiExpr = CREATE(function_item)(theRootSctx, theUDF, loc,
- closureSctx,
f,
f->getName(),
arity,
- false,
+ false, // not inline
needs_context_item,
- false);
+ false); // not coersion
return fiExpr;
}
@@ -11994,16 +11956,13 @@
push_scope();
- static_context* closureSctx = theRootSctx->create_child_context();
- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
-
function_item_expr* fiExpr =
- CREATE(function_item)(theRootSctx, theUDF, loc, closureSctx, true, false, false);
+ CREATE(function_item)(theRootSctx, theUDF, loc, true, false, false);
push_nodestack(fiExpr);
// Translate the return tyoe
- xqtref_t returnType = GENV_TYPESYSTEM.ITEM_TYPE_STAR;
+ xqtref_t returnType = theRTM.ITEM_TYPE_STAR;
if (v.getReturnType() != 0)
{
v.getReturnType()->accept(*this);
@@ -12023,7 +11982,7 @@
const SequenceType* paramType = param->get_typedecl();
if (paramType == 0)
{
- paramTypes.push_back(GENV_TYPESYSTEM.ITEM_TYPE_STAR);
+ paramTypes.push_back(theRTM.ITEM_TYPE_STAR);
}
else
{
@@ -12050,7 +12009,7 @@
}
else
{
- flwor = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
+ flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
}
// Handle inscope variables. For each inscope var, a let binding is added to
=== modified file 'src/runtime/function_item/function_item.cpp'
--- src/runtime/function_item/function_item.cpp 2013-03-17 15:07:49 +0000
+++ src/runtime/function_item/function_item.cpp 2013-03-23 15:23:24 +0000
@@ -64,8 +64,8 @@
bool isCoercion)
:
theMustDeleteCCB(false),
+ theLoc(loc),
theClosureSctx(closureSctx),
- theLoc(loc),
theFunction(func),
theQName(qname),
theArity(arity),
@@ -249,14 +249,10 @@
}
}
-// if (theDynamicFunctionInfo->theCCB != NULL)
-// ccb = theDynamicFunctionInfo->theCCB;
-
expr* dummy = ccb->theEM->
create_function_item_expr(NULL,
NULL,
theDynamicFunctionInfo->theLoc,
- NULL,
false,
false,
false);
=== modified file 'src/runtime/function_item/function_item.h'
--- src/runtime/function_item/function_item.h 2013-03-17 14:11:09 +0000
+++ src/runtime/function_item/function_item.h 2013-03-23 15:23:24 +0000
@@ -44,7 +44,71 @@
theMustDeleteCCB :
------------------
This is set to true if the DynamicFunctionInfo is the owner of the CCB,
- and must delete it upon destruction.
+ and must delete it upon destruction.
+
+ theLoc:
+ -------
+ The location where the function item expr or inline function expr appear at.
+
+ theClosureSctx:
+ ---------------
+ The static context to be used when the function item is actually invoked.
+
+ theFunction:
+ ------------
+ The function obj that represents the implementation of this function item.
+ This is always a pointer to a user_function obj. In case of an inline function
+ expr, it is an anonymous user_function obj that is created on-the-fly by the
+ translator to represent the body and signature of the inline function. In case
+ of a function item expr where the named function is a UDF, it is the
+ user_function obj of that UDF. Finally, in case of a function item expr where
+ the named function F is not a UDF, it is a user_function obj UF that is created
+ on-the-fly by the translator. The signature of UF is the same as that of F, and
+ its body simply invokes F. The reason why UF is built is to unify the
+ implemenation of dynamic function invocation.
+
+ theQName:
+ ---------
+
+ theArity:
+ ---------
+ We need to store the arity also here because the function obj above doesn't
+ know about its arity in case it's a variadic function.
+
+ theIsInline:
+ ------------
+
+ theNeedsContextItem:
+ --------------------
+ Whether the function is a contextual one, i.e., accesses the context item, or
+ context position, or context size directly.
+
+ theIsCoercion:
+ --------------
+ This is set to true if the function item is a function coercion. In this
+ case the newly created function item's name is taken from the coerced
+ function.
+
+ theScopedVarsValues:
+ --------------------
+ Empty in the case of LiteralFunctionItem. Otherwise, the vars that are in
+ scope at the place where the InlineFunction expr appears at.
+
+ theSubstVarsValues:
+ -------------------
+
+ theScopedVarsNames:
+ -------------------
+
+ theIsGlobalVar:
+ ---------------
+
+ theVarId:
+ ---------
+
+ theScopedVarsIteratosr:
+ -----------------------
+
********************************************************************************/
class DynamicFunctionInfo : public SimpleRCObject
{
@@ -52,16 +116,14 @@
CompilerCB * theCCB;
bool theMustDeleteCCB;
+ QueryLoc theLoc;
static_context * theClosureSctx;
- QueryLoc theLoc;
function_t theFunction;
store::Item_t theQName;
unsigned int theArity;
bool theIsInline;
bool theNeedsContextItem;
- bool theIsCoercion; // This is set to true if the function item is a function coercion. In this
- // case the newly created function item's name is taken from the coerced
- // function.
+ bool theIsCoercion;
std::vector<expr*> theScopedVarsValues;
std::vector<var_expr*> theSubstVarsValues;
@@ -102,7 +164,6 @@
/*******************************************************************************
A FunctionItem is created during codegen, when a function_item_expr is reached.
- theCCB :
theSctx : The static context of the function_item_expr.
theExpr : The associated function_item_expr.
theVariableValues : Vector of var iterators representing the values of the
@@ -129,8 +190,9 @@
void serialize(::zorba::serialization::Archiver& ar);
public:
- FunctionItem(const DynamicFunctionInfo_t& dynamicFunctionInfo,
- dynamic_context* dctx);
+ FunctionItem(
+ const DynamicFunctionInfo_t& dynamicFunctionInfo,
+ dynamic_context* dctx);
SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; })
=== modified file 'test/fots/CMakeLists.txt'
--- test/fots/CMakeLists.txt 2013-03-22 04:37:29 +0000
+++ test/fots/CMakeLists.txt 2013-03-23 15:23:24 +0000
@@ -641,7 +641,6 @@
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-376 0)
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-402 0)
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-404 0)
-EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-430 0)
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-494 0)
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-523 0)
EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-524 0)
@@ -682,7 +681,6 @@
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-376 0)
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-402 0)
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-404 0)
-EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-430 0)
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-494 0)
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-523 0)
EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-524 0)
Follow ups