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)

-- 
Mailing list: https://launchpad.net/~zorba-coders
Post to     : zorba-coders@lists.launchpad.net
Unsubscribe : https://launchpad.net/~zorba-coders
More help   : https://help.launchpad.net/ListHelp

Reply via email to