Merge lp:~zorba-coders/zorba/hof-merge into lp:zorba

Proposed by Markos Zaharioudakis
Status: Merged
Approved by: Markos Zaharioudakis
Approved revision: 10728
Merged at revision: 11307
Proposed branch: lp:~zorba-coders/zorba/hof-merge
Merge into: lp:zorba
Diff against target: 1671 lines (+568/-573)
9 files modified
src/compiler/expression/expr_clone.cpp (+14/-6)
src/compiler/expression/expr_manager.cpp (+10/-18)
src/compiler/expression/expr_manager.h (+2/-12)
src/compiler/expression/function_item_expr.cpp (+40/-31)
src/compiler/expression/function_item_expr.h (+2/-21)
src/compiler/translator/translator.cpp (+429/-470)
src/runtime/function_item/function_item.cpp (+1/-5)
src/runtime/function_item/function_item.h (+70/-8)
test/fots/CMakeLists.txt (+0/-2)
To merge this branch: bzr merge lp:~zorba-coders/zorba/hof-merge
Reviewer Review Type Date Requested Status
Markos Zaharioudakis Approve
Review via email: mp+155100@code.launchpad.net

Commit message

cleanup + fixed 2 hof tests concerning the fn:fold-right function

Description of the change

cleanup + fixed 2 hof tests concerning the fn:fold-right function

To post a comment you must log in.
lp:~zorba-coders/zorba/hof-merge updated
10728. By Markos Zaharioudakis

merge from trunk

Revision history for this message
Markos Zaharioudakis (markos-za) :
review: Approve
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :
Revision history for this message
Zorba Build Bot (zorba-buildbot) wrote :

Validation queue job hof-merge-2013-03-23T15-36-58.877Z is finished. The final status was:

All tests succeeded!

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/compiler/expression/expr_clone.cpp'
2--- src/compiler/expression/expr_clone.cpp 2013-03-21 18:53:47 +0000
3+++ src/compiler/expression/expr_clone.cpp 2013-03-23 15:26:22 +0000
4@@ -386,7 +386,6 @@
5 create_function_item_expr(theSctx,
6 udf,
7 get_loc(),
8- e->theDynamicFunctionInfo->theClosureSctx,
9 e->theDynamicFunctionInfo->theFunction,
10 e->theDynamicFunctionInfo->theFunction->getName(),
11 e->theDynamicFunctionInfo->theArity,
12@@ -394,11 +393,20 @@
13 e->needs_context_item(),
14 e->is_coercion());
15
16- std::vector<expr*>::const_iterator varIter = e->theDynamicFunctionInfo->theScopedVarsValues.begin();
17- std::vector<var_expr*>::const_iterator substVarIter = e->theDynamicFunctionInfo->theSubstVarsValues.begin();
18- std::vector<store::Item_t>::const_iterator nameIter = e->theDynamicFunctionInfo->theScopedVarsNames.begin();
19- std::vector<int>::const_iterator isGlobalIter = e->theDynamicFunctionInfo->theIsGlobalVar.begin();
20- for (; varIter != e->theDynamicFunctionInfo->theScopedVarsValues.end(); ++varIter, ++substVarIter, ++nameIter, ++isGlobalIter)
21+ std::vector<expr*>::const_iterator varIter =
22+ e->theDynamicFunctionInfo->theScopedVarsValues.begin();
23+
24+ std::vector<var_expr*>::const_iterator substVarIter =
25+ e->theDynamicFunctionInfo->theSubstVarsValues.begin();
26+
27+ std::vector<store::Item_t>::const_iterator nameIter =
28+ e->theDynamicFunctionInfo->theScopedVarsNames.begin();
29+
30+ std::vector<int>::const_iterator isGlobalIter =
31+ e->theDynamicFunctionInfo->theIsGlobalVar.begin();
32+
33+ for (; varIter != e->theDynamicFunctionInfo->theScopedVarsValues.end();
34+ ++varIter, ++substVarIter, ++nameIter, ++isGlobalIter)
35 {
36 cloneExpr->add_variable((*varIter) ? (*varIter)->clone(udf, subst) : NULL,
37 (*substVarIter) ? static_cast<var_expr*>((*substVarIter)->clone(udf, subst)) : NULL,
38
39=== modified file 'src/compiler/expression/expr_manager.cpp'
40--- src/compiler/expression/expr_manager.cpp 2013-03-17 13:44:16 +0000
41+++ src/compiler/expression/expr_manager.cpp 2013-03-23 15:26:22 +0000
42@@ -496,16 +496,6 @@
43 CREATE_AND_RETURN_EXPR(wrapper_expr, sctx, udf, loc, wrapped);
44 }
45
46-#if 0
47-function_trace_expr* ExprManager::create_function_trace_expr(
48- static_context* sctx,
49- user_function* udf,
50- const QueryLoc& loc,
51- expr* aChild)
52-{
53- CREATE_AND_RETURN_EXPR(function_trace_expr, sctx, udf, loc, aChild);
54-}
55-#endif
56
57 function_trace_expr* ExprManager::create_function_trace_expr(
58 user_function* udf,
59@@ -818,30 +808,32 @@
60 }
61
62
63-function_item_expr* ExprManager::create_function_item_expr(static_context* sctx,
64+function_item_expr* ExprManager::create_function_item_expr(
65+ static_context* sctx,
66 user_function* udf,
67 const QueryLoc& loc,
68- static_context* closureSctx,
69 function* f,
70- store::Item* aQName,
71- uint32_t aArity,
72+ store::Item* qname,
73+ uint32_t arity,
74 bool isInline,
75 bool needsContextItem,
76 bool isCoercion)
77 {
78- CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc, closureSctx, f, aQName, aArity, isInline, needsContextItem, isCoercion);
79+ CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc,
80+ f, qname, arity, isInline, needsContextItem, isCoercion);
81 }
82
83
84-function_item_expr* ExprManager::create_function_item_expr(static_context* sctx,
85+function_item_expr* ExprManager::create_function_item_expr(
86+ static_context* sctx,
87 user_function* udf,
88 const QueryLoc& loc,
89- static_context *closureSctx,
90 bool isInline,
91 bool needsContextItem,
92 bool isCoercion)
93 {
94- CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc, closureSctx, isInline, needsContextItem, isCoercion);
95+ CREATE_AND_RETURN_EXPR(function_item_expr, sctx, udf, loc,
96+ isInline, needsContextItem, isCoercion);
97 }
98
99
100
101=== modified file 'src/compiler/expression/expr_manager.h'
102--- src/compiler/expression/expr_manager.h 2013-03-17 13:44:16 +0000
103+++ src/compiler/expression/expr_manager.h 2013-03-23 15:26:22 +0000
104@@ -306,14 +306,6 @@
105 const QueryLoc& loc,
106 expr* wrapped);
107
108-#if 0
109- function_trace_expr* create_function_trace_expr(
110- static_context* sctx,
111- user_function* udf,
112- const QueryLoc& loc,
113- expr* aChild);
114-#endif
115-
116 function_trace_expr* create_function_trace_expr(
117 user_function* udf,
118 expr* aExpr);
119@@ -500,10 +492,9 @@
120 function_item_expr* create_function_item_expr(static_context* sctx,
121 user_function* udf,
122 const QueryLoc& loc,
123- static_context *closureSctx,
124 function* f,
125- store::Item* aQName,
126- uint32_t aArity,
127+ store::Item* qname,
128+ uint32_t arity,
129 bool isInline,
130 bool needsContextItem,
131 bool isCoercion);
132@@ -512,7 +503,6 @@
133 static_context* sctx,
134 user_function* udf,
135 const QueryLoc& loc,
136- static_context *closureSctx,
137 bool isInline,
138 bool needsContextItem,
139 bool isCoercion);
140
141=== modified file 'src/compiler/expression/function_item_expr.cpp'
142--- src/compiler/expression/function_item_expr.cpp 2013-03-17 13:55:28 +0000
143+++ src/compiler/expression/function_item_expr.cpp 2013-03-23 15:26:22 +0000
144@@ -29,7 +29,9 @@
145 namespace zorba {
146
147
148-DEF_EXPR_ACCEPT (dynamic_function_invocation_expr);
149+/*******************************************************************************
150+
151+********************************************************************************/
152
153
154 dynamic_function_invocation_expr::dynamic_function_invocation_expr(
155@@ -61,47 +63,47 @@
156 }
157
158
159+DEF_EXPR_ACCEPT(dynamic_function_invocation_expr);
160+
161+
162 /*******************************************************************************
163
164 ********************************************************************************/
165
166+void argument_placeholder_expr::compute_scripting_kind()
167+{
168+ theScriptingKind = SIMPLE_EXPR;
169+}
170+
171+
172 DEF_EXPR_ACCEPT (argument_placeholder_expr);
173
174-void argument_placeholder_expr::compute_scripting_kind()
175-{
176- theScriptingKind = SIMPLE_EXPR;
177-}
178-
179
180 /*******************************************************************************
181
182 ********************************************************************************/
183
184-DEF_EXPR_ACCEPT (function_item_expr);
185-
186
187 function_item_expr::function_item_expr(CompilerCB* ccb,
188 static_context* sctx,
189 user_function* udf,
190 const QueryLoc& loc,
191- static_context* closureSctx,
192 function* f,
193- store::Item* aQName,
194- uint32_t aArity,
195+ store::Item* qname,
196+ uint32_t arity,
197 bool isInline,
198 bool needsContextItem,
199 bool isCoercion)
200 :
201 expr(ccb, sctx, udf, loc, function_item_expr_kind),
202- theDynamicFunctionInfo(new DynamicFunctionInfo(
203- closureSctx,
204- loc,
205- f,
206- aQName,
207- aArity,
208- isInline,
209- needsContextItem,
210- isCoercion))
211+ theDynamicFunctionInfo(new DynamicFunctionInfo(sctx,
212+ loc,
213+ f,
214+ qname,
215+ arity,
216+ isInline,
217+ needsContextItem,
218+ isCoercion))
219 {
220 assert(f != NULL);
221 compute_scripting_kind();
222@@ -112,21 +114,19 @@
223 static_context* sctx,
224 user_function* udf,
225 const QueryLoc& loc,
226- static_context* closureSctx,
227 bool isInline,
228 bool needsContextItem,
229 bool isCoercion)
230 :
231 expr(ccb, sctx, udf, loc, function_item_expr_kind),
232- theDynamicFunctionInfo(new DynamicFunctionInfo(
233- closureSctx,
234- loc,
235- NULL,
236- NULL,
237- 0,
238- isInline,
239- needsContextItem,
240- isCoercion))
241+ theDynamicFunctionInfo(new DynamicFunctionInfo(sctx,
242+ loc,
243+ NULL,
244+ NULL,
245+ 0,
246+ isInline,
247+ needsContextItem,
248+ isCoercion))
249 {
250 theScriptingKind = SIMPLE_EXPR;
251 }
252@@ -136,7 +136,12 @@
253 {
254 }
255
256-void function_item_expr::add_variable(expr* var, var_expr* substVar, const store::Item_t& name, int isGlobal)
257+
258+void function_item_expr::add_variable(
259+ expr* var,
260+ var_expr* substVar,
261+ const store::Item_t& name,
262+ int isGlobal)
263 {
264 theDynamicFunctionInfo->add_variable(var, substVar, name, isGlobal);
265 }
266@@ -157,6 +162,7 @@
267 theScriptingKind = SIMPLE_EXPR;
268 }
269
270+
271 store::Item_t function_item_expr::create_inline_fname(const QueryLoc& loc)
272 {
273 store::Item_t name;
274@@ -169,5 +175,8 @@
275 }
276
277
278+DEF_EXPR_ACCEPT (function_item_expr);
279+
280+
281 }//end of namespace
282 /* vim:set et sw=2 ts=2: */
283
284=== modified file 'src/compiler/expression/function_item_expr.h'
285--- src/compiler/expression/function_item_expr.h 2013-03-17 13:44:16 +0000
286+++ src/compiler/expression/function_item_expr.h 2013-03-23 15:26:22 +0000
287@@ -85,7 +85,8 @@
288 expr * theDotVar;
289
290 protected:
291- dynamic_function_invocation_expr(CompilerCB* ccb,
292+ dynamic_function_invocation_expr(
293+ CompilerCB* ccb,
294 static_context* sctx,
295 user_function* udf,
296 const QueryLoc& loc,
297@@ -116,24 +117,6 @@
298
299 InlineFunction ::= "function" "(" ParamList? ")" ("as" SequenceType)? EnclosedExpr
300
301- theFunction :
302- This is always a pointer to a user_function obj. In case of an inline function
303- expr, it is an anonymous user_function obj that is created on-the-fly by the
304- translator to represent the body and signature of the inline function. In case
305- of LiteralFunctionItem where the named function is a UDF, it is the
306- user_function obj of that UDF. Finally, in case of LiteralFunctionItem where
307- the named function F is not a UDF, it is an anonymous user_function obj UF
308- that is created on-the-fly by the translator. The signature of UF is the same
309- as that of F, and its body simply invokes F. The reason why UF is built is to
310- unify the implemenation of dynamic function invocation.
311-
312- theArity :
313- We need to store the arity also here because the function above doesn't know
314- about its arity in case it's a variadic function.
315-
316- theScopedVariables :
317- Empty in the case of LiteralFunctionItem. Otherwise, the FLWOR vars that are
318- in scope at the place where the InlineFunction expr appears at.
319 ********************************************************************************/
320 class function_item_expr: public expr
321 {
322@@ -150,7 +133,6 @@
323 static_context* sctx,
324 user_function* udf,
325 const QueryLoc& loc,
326- static_context* closureSctx,
327 function* f,
328 store::Item* aQName,
329 uint32_t aArity,
330@@ -163,7 +145,6 @@
331 static_context* sctx,
332 user_function* udf,
333 const QueryLoc& loc,
334- static_context* closureSctx,
335 bool isInline,
336 bool needsContextItem,
337 bool isCoercion);
338
339=== modified file 'src/compiler/translator/translator.cpp'
340--- src/compiler/translator/translator.cpp 2013-03-20 23:33:11 +0000
341+++ src/compiler/translator/translator.cpp 2013-03-23 15:26:22 +0000
342@@ -1378,6 +1378,165 @@
343 }
344
345
346+
347+/*******************************************************************************
348+
349+********************************************************************************/
350+void normalize_fo(fo_expr* foExpr)
351+{
352+ const QueryLoc& loc = foExpr->get_loc();
353+
354+ csize n = foExpr->num_args();
355+
356+ const function* func = foExpr->get_func();
357+ FunctionConsts::FunctionKind fkind = func->getKind();
358+
359+ if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
360+ fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
361+ {
362+ csize nStarterParams =
363+ (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ? 1 : 2);
364+
365+ if (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
366+ {
367+ const store::Item* qname = NULL;
368+
369+ if (n > 0)
370+ qname = foExpr->get_arg(0)->getQName();
371+
372+ zstring lMsgPart;
373+ ztd::to_string(nStarterParams, &lMsgPart);
374+ lMsgPart += " + multiple of 6";
375+ if (qname != NULL)
376+ {
377+ RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
378+ ERROR_PARAMS(qname->getStringValue(), "index", n, lMsgPart));
379+ }
380+ else
381+ {
382+ RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
383+ ERROR_PARAMS("anonymous", "index", n, lMsgPart));
384+ }
385+ }
386+ }
387+
388+ for (csize i = 0; i < n; ++i)
389+ {
390+ expr* argExpr = foExpr->get_arg(i);
391+
392+ argExpr = normalize_fo_arg(i, argExpr, func, loc);
393+
394+ foExpr->set_arg(i, argExpr);
395+ }
396+}
397+
398+
399+/*******************************************************************************
400+
401+********************************************************************************/
402+expr* normalize_fo_arg(
403+ csize i,
404+ expr* argExpr,
405+ const function* func,
406+ const QueryLoc& loc)
407+{
408+ xqtref_t paramType;
409+
410+ const signature& sign = func->getSignature();
411+
412+ TypeManager* tm = argExpr->get_type_manager();
413+
414+ switch (func->getKind())
415+ {
416+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N:
417+ {
418+ if (i == 0)
419+ paramType = sign[i];
420+ else
421+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
422+
423+ break;
424+ }
425+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N:
426+ {
427+ if (i <= 1)
428+ paramType = sign[i];
429+ else
430+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
431+
432+ break;
433+ }
434+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N:
435+ {
436+ if (i == 0)
437+ paramType = sign[i];
438+ else if (i % 6 == 1 || i % 6 == 2)
439+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
440+ else
441+ paramType = theRTM.BOOLEAN_TYPE_ONE;
442+
443+ break;
444+ }
445+ case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N:
446+ {
447+ if (i <= 1)
448+ paramType = sign[i];
449+ else if (i % 6 == 2 || i % 6 == 3)
450+ paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
451+ else
452+ paramType = theRTM.BOOLEAN_TYPE_ONE;
453+
454+ break;
455+ }
456+ case FunctionConsts::FN_ZORBA_INVOKE_N:
457+ case FunctionConsts::FN_ZORBA_INVOKE_N_N:
458+ case FunctionConsts::FN_ZORBA_INVOKE_U_N:
459+ case FunctionConsts::FN_ZORBA_INVOKE_S_N:
460+ {
461+ if (i == 0)
462+ paramType = sign[i];
463+ else
464+ paramType = NULL; // Nothing to check as the target function is not known
465+
466+ break;
467+ }
468+ default:
469+ {
470+ paramType = sign[i];
471+ }
472+ }
473+
474+ // A NULL value for the parameter's type to signal that no type promotion
475+ // or match should be added. This is used by the reflection:invoke() function,
476+ if (paramType != NULL)
477+ {
478+ if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
479+ {
480+ argExpr = wrap_in_type_promotion(argExpr,
481+ paramType,
482+ PROMOTE_FUNC_PARAM,
483+ func->getName());
484+ }
485+ else
486+ {
487+ if (paramType->type_kind() == XQType::FUNCTION_TYPE_KIND)
488+ {
489+ // function coercion
490+ argExpr = wrap_in_coercion(paramType, argExpr, loc, theCCB);
491+ }
492+
493+ argExpr = wrap_in_type_match(argExpr,
494+ paramType,
495+ loc,
496+ TREAT_FUNC_PARAM,
497+ func->getName());
498+ }
499+ }
500+
501+ return argExpr;
502+}
503+
504+
505 /*******************************************************************************
506
507 ********************************************************************************/
508@@ -1392,15 +1551,15 @@
509
510 // Create the dynamic call body
511
512- static_context* closureSctx = theRootSctx->create_child_context();
513- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
514- function_item_expr* fiExpr = theExprManager->create_function_item_expr(theRootSctx, theUDF, loc, closureSctx, true, false, true /* isCoercion */);
515+ function_item_expr* fiExpr =
516+ CREATE(function_item)(theRootSctx, theUDF, loc, true, false, true);
517+
518 push_nodestack(fiExpr);
519
520 push_scope();
521
522 // handle the function item expression
523- flwor_expr* fnItem_flwor = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
524+ flwor_expr* fnItem_flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
525 for_clause* fnItem_fc = wrap_in_forclause(theExpr, NULL);
526 var_expr* fnItem_var = fnItem_fc->get_var();
527 fnItem_flwor->add_clause(fnItem_fc);
528@@ -1408,13 +1567,13 @@
529 fiExpr->add_variable(fnItem_var, inner_subst_var, fnItem_var->get_name(), 0 /*var is not global*/);
530
531 // bind the function item variable in the inner flwor
532- flwor_expr* inner_flwor = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
533+ flwor_expr* inner_flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
534 var_expr* inner_arg_var = create_var(loc, fnItem_var->get_name(), var_expr::let_var);
535 inner_arg_var->set_param_pos(inner_flwor->num_clauses());
536
537 // Handle parameters. For each parameter, a let binding is added to the inner flwor.
538 std::vector<expr*> arguments; // Arguments to the dynamic function call
539- for(unsigned i = 0; i<func_type->get_number_params(); i++)
540+ for(csize i = 0; i < func_type->get_number_params(); i++)
541 {
542 xqtref_t paramType = func_type->operator[](i);
543
544@@ -1427,7 +1586,7 @@
545
546 inner_flwor->add_clause(lc);
547
548- arguments.push_back(theExprManager->create_wrapper_expr(theRootSctx, theUDF, loc, subst_var));
549+ arguments.push_back(CREATE(wrapper)(theRootSctx, theUDF, loc, subst_var));
550 }
551
552 if (inner_flwor->num_clauses() == 0)
553@@ -1435,13 +1594,13 @@
554 inner_flwor = NULL;
555 }
556
557- expr* body = CREATE(dynamic_function_invocation)(
558- theRootSctx,
559- theUDF,
560- loc,
561- CREATE(wrapper)(theRootSctx, theUDF, loc, inner_subst_var),
562- arguments,
563- NULL);
564+ expr* body =
565+ CREATE(dynamic_function_invocation)(theRootSctx,
566+ theUDF,
567+ loc,
568+ CREATE(wrapper)(theRootSctx, theUDF, loc, inner_subst_var),
569+ arguments,
570+ NULL);
571
572 create_inline_function(body,
573 inner_flwor,
574@@ -1462,164 +1621,6 @@
575
576
577 /*******************************************************************************
578-
579-********************************************************************************/
580-expr* normalize_fo_arg(
581- csize i,
582- expr* argExpr,
583- const function* func,
584- const QueryLoc& loc)
585-{
586- xqtref_t paramType;
587-
588- const signature& sign = func->getSignature();
589-
590- TypeManager* tm = argExpr->get_type_manager();
591-
592- switch (func->getKind())
593- {
594- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_N:
595- {
596- if (i == 0)
597- paramType = sign[i];
598- else
599- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
600-
601- break;
602- }
603- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_VALUE_SKIP_N:
604- {
605- if (i <= 1)
606- paramType = sign[i];
607- else
608- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
609-
610- break;
611- }
612- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N:
613- {
614- if (i == 0)
615- paramType = sign[i];
616- else if (i % 6 == 1 || i % 6 == 2)
617- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
618- else
619- paramType = theRTM.BOOLEAN_TYPE_ONE;
620-
621- break;
622- }
623- case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N:
624- {
625- if (i <= 1)
626- paramType = sign[i];
627- else if (i % 6 == 2 || i % 6 == 3)
628- paramType = theRTM.ANY_ATOMIC_TYPE_QUESTION;
629- else
630- paramType = theRTM.BOOLEAN_TYPE_ONE;
631-
632- break;
633- }
634- case FunctionConsts::FN_ZORBA_INVOKE_N:
635- case FunctionConsts::FN_ZORBA_INVOKE_N_N:
636- case FunctionConsts::FN_ZORBA_INVOKE_U_N:
637- case FunctionConsts::FN_ZORBA_INVOKE_S_N:
638- {
639- if (i == 0)
640- paramType = sign[i];
641- else
642- paramType = NULL; // Nothing to check as the target function is not known
643-
644- break;
645- }
646- default:
647- {
648- paramType = sign[i];
649- }
650- }
651-
652- // A NULL value for the parameter's type to signal that no type promotion
653- // or match should be added. This is used by the reflection:invoke() function,
654- if (paramType != NULL)
655- {
656- if (TypeOps::is_subtype(tm, *paramType, *theRTM.ANY_ATOMIC_TYPE_STAR, loc))
657- {
658- argExpr = wrap_in_type_promotion(argExpr,
659- paramType,
660- PROMOTE_FUNC_PARAM,
661- func->getName());
662- }
663- else
664- {
665- if (paramType->type_kind() == XQType::FUNCTION_TYPE_KIND)
666- {
667- // function coercion
668- argExpr = wrap_in_coercion(paramType, argExpr, loc, theCCB);
669- }
670-
671- argExpr = wrap_in_type_match(argExpr,
672- paramType,
673- loc,
674- TREAT_FUNC_PARAM,
675- func->getName());
676- }
677- }
678-
679- return argExpr;
680-}
681-
682-
683-/*******************************************************************************
684-
685-********************************************************************************/
686-void normalize_fo(fo_expr* foExpr)
687-{
688- const QueryLoc& loc = foExpr->get_loc();
689-
690- csize n = foExpr->num_args();
691-
692- const function* func = foExpr->get_func();
693- FunctionConsts::FunctionKind fkind = func->getKind();
694-
695- if (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ||
696- fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_SKIP_N)
697- {
698- csize nStarterParams =
699- (fkind == FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_VALUE_N ? 1 : 2);
700-
701- if (n < (6 + nStarterParams) || (n - nStarterParams) % 6 != 0)
702- {
703- const store::Item* qname = NULL;
704-
705- if (n > 0)
706- qname = foExpr->get_arg(0)->getQName();
707-
708- zstring lMsgPart;
709- ztd::to_string(nStarterParams, &lMsgPart);
710- lMsgPart += " + multiple of 6";
711- if (qname != NULL)
712- {
713- RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
714- ERROR_PARAMS(qname->getStringValue(), "index", n, lMsgPart));
715- }
716- else
717- {
718- RAISE_ERROR(zerr::ZDDY0025_INDEX_WRONG_NUMBER_OF_PROBE_ARGS, loc,
719- ERROR_PARAMS("anonymous", "index", n, lMsgPart));
720- }
721- }
722- }
723-
724- for (csize i = 0; i < n; ++i)
725- {
726- expr* argExpr = foExpr->get_arg(i);
727-
728- argExpr = normalize_fo_arg(i, argExpr, func, loc);
729-
730- foExpr->set_arg(i, argExpr);
731- }
732-}
733-
734-
735-/*******************************************************************************
736 Wrap the given expr in an fn:data() function
737 ********************************************************************************/
738 expr* wrap_in_atomization(expr* e)
739@@ -10911,6 +10912,8 @@
740 arguments.push_back(argExpr);
741 }
742
743+ std::reverse(arguments.begin(), arguments.end());
744+
745 csize numArgs = arguments.size();
746
747 // Lookup the function
748@@ -10936,12 +10939,8 @@
749 const QueryLoc& loc)
750 {
751 TypeManager* tm = CTX_TM;
752-
753- expr* resultExpr = NULL;
754-
755 store::Item_t qnameItem;
756 zstring fn_ns;
757-
758 csize numArgs = arguments.size();
759
760 if (f == NULL)
761@@ -10995,21 +10994,11 @@
762 ERROR_PARAMS(fn_ns));
763 }
764
765- // Add context-item for functions with zero arguments which implicitly
766- // take the context-item as argument
767- if (xquery_fns_def_dot.test(f->getKind()))
768- {
769- arguments.push_back(DOT_REF);
770- f = theSctx->lookup_fn(qnameItem, 1, loc);
771- }
772-
773 // Check if it is a zorba builtin function, and if so,
774 // make sure that the module it belongs to has been imported.
775 if (f->isBuiltin() &&
776 fn_ns != static_context::W3C_FN_NS &&
777-#ifdef ZORBA_WITH_JSON
778 fn_ns != static_context::JSONIQ_FN_NS &&
779-#endif
780 fn_ns != XQUERY_MATH_FN_NS &&
781 fn_ns != theModuleNamespace)
782 {
783@@ -11020,168 +11009,16 @@
784 }
785 }
786
787- // Special processing for certain builtin functions
788- switch (f->getKind())
789- {
790- case FunctionConsts::FN_HEAD_1:
791- case FunctionConsts::FN_TAIL_1:
792- case FunctionConsts::FN_NUMBER_1:
793- case FunctionConsts::FN_POSITION_0:
794- case FunctionConsts::FN_LAST_0:
795- case FunctionConsts::FN_STATIC_BASE_URI_0:
796- case FunctionConsts::FN_APPLY_1:
797- {
798- resultExpr = generate_fn_body(f, arguments, loc);
799- break;
800- }
801- case FunctionConsts::FN_IDREF_1:
802- {
803- arguments.insert(arguments.begin(), DOT_REF);
804- f = BUILTIN_FUNC(FN_IDREF_2);
805- break;
806- }
807- case FunctionConsts::FN_LANG_1:
808- {
809- arguments.insert(arguments.begin(), DOT_REF);
810- f = BUILTIN_FUNC(FN_LANG_2);
811- break;
812- }
813- case FunctionConsts::FN_RESOLVE_URI_1:
814- {
815- zstring baseUri = theSctx->get_base_uri();
816- arguments.insert(arguments.begin(),
817- CREATE(const)(theRootSctx, theUDF, loc, baseUri));
818- f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
819- break;
820- }
821- case FunctionConsts::FN_SUBSEQUENCE_2:
822- case FunctionConsts::FN_SUBSEQUENCE_3:
823- case FunctionConsts::FN_SUBSTRING_2:
824- case FunctionConsts::FN_SUBSTRING_3:
825- {
826- if (numArgs == 2)
827- {
828- xqtref_t posType = arguments[0]->get_return_type();
829-
830- if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc))
831- {
832- if (f->getKind() == FunctionConsts::FN_SUBSTRING_2)
833- f = BUILTIN_FUNC(OP_SUBSTRING_INT_2);
834- else
835- f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_2);
836- }
837- }
838- else
839- {
840- xqtref_t posType = arguments[1]->get_return_type();
841- xqtref_t lenType = arguments[0]->get_return_type();
842-
843- if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc) &&
844- TypeOps::is_subtype(tm, *lenType, *theRTM.INTEGER_TYPE_STAR, loc))
845- {
846- if (f->getKind() == FunctionConsts::FN_SUBSTRING_3)
847- f = BUILTIN_FUNC(OP_SUBSTRING_INT_3);
848- else
849- f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_3);
850- }
851- }
852-
853- break;
854- }
855- case FunctionConsts::FN_ID_1:
856- case FunctionConsts::FN_ID_2:
857- case FunctionConsts::FN_ELEMENT_WITH_ID_1:
858- case FunctionConsts::FN_ELEMENT_WITH_ID_2:
859- {
860- if (numArgs == 1)
861- {
862- arguments.insert(arguments.begin(), DOT_REF);
863- f = theSctx->lookup_fn(qnameItem, 2, loc);
864- }
865-
866- expr* idsExpr = arguments[1];
867-
868- flwor_expr* flworExpr = wrap_expr_in_flwor(idsExpr, false);
869-
870- const for_clause* fc = static_cast<const for_clause*>(flworExpr->get_clause(0));
871- expr* flworVarExpr = fc->get_var();
872-
873- fo_expr* normExpr = NULL;
874- fo_expr* tokenExpr = NULL;
875- zstring space(" ");
876- const_expr* constExpr = CREATE(const)(theRootSctx, theUDF, loc, space);
877-
878- normExpr = CREATE(fo)(theRootSctx, theUDF, loc,
879- BUILTIN_FUNC(FN_NORMALIZE_SPACE_1),
880- flworVarExpr);
881- normalize_fo(normExpr);
882-
883- tokenExpr = CREATE(fo)(theRootSctx, theUDF, loc,
884- BUILTIN_FUNC(FN_TOKENIZE_2),
885- normExpr,
886- constExpr);
887- normalize_fo(tokenExpr);
888-
889- flworExpr->set_return_expr(tokenExpr);
890-
891- pop_scope();
892-
893- arguments[1] = flworExpr;
894- break;
895- }
896- case FunctionConsts::FN_FOLD_RIGHT_3:
897- {
898- // Because arguments are reversed, the 3rd argument is actually arguments[0]
899- arguments[0] = CREATE(fo)(theRootSctx, theUDF, loc,
900- BUILTIN_FUNC(FN_REVERSE_1),
901- arguments[0]);
902- break;
903- }
904- case FunctionConsts::FN_CONCAT_N:
905- {
906- if (numArgs < 2)
907- {
908- RAISE_ERROR(err::XPST0017, loc,
909- ERROR_PARAMS("concat", ZED(FunctionUndeclared_3), numArgs));
910- }
911- break;
912- }
913- case FunctionConsts::FN_DOC_1:
914- {
915- expr* doc_uri = arguments[0];
916-
917- //validate uri
918- if (doc_uri->get_expr_kind() == const_expr_kind)
919- {
920- const_expr* const_uri = reinterpret_cast<const_expr*>(doc_uri);
921- const store::Item* uri_value = const_uri->get_val();
922- zstring uri_string = uri_value->getStringValue();
923-
924- try
925- {
926- if (uri_string.find(":/", 0, 3) != zstring::npos)
927- {
928- URI docURI(uri_string, true);//with validate
929- }
930- }
931- catch(XQueryException& e)
932- {
933- set_source(e, loc);
934- throw;
935- }
936- }
937- break;
938- }
939- default:
940- {
941- }
942- }
943-
944- if (resultExpr)
945- {
946- f->processPragma(resultExpr, theScopedPragmas);
947- return resultExpr;
948- }
949+ // Add context-item for functions with zero arguments which implicitly
950+ // take the context-item as argument
951+ if (xquery_fns_def_dot.test(f->getKind()))
952+ {
953+ assert(arguments.empty());
954+ arguments.push_back(DOT_REF);
955+ f = theSctx->lookup_fn(qnameItem, 1, loc);
956+ }
957+
958+ expr* resultExpr = generate_fn_body(f, arguments, loc);
959
960 numArgs = arguments.size(); // recompute size
961
962@@ -11198,20 +11035,12 @@
963 }
964 }
965
966- // Create and normalize the fo expr
967- std::reverse(arguments.begin(), arguments.end());
968-
969- fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
970- normalize_fo(foExpr);
971-
972- resultExpr = foExpr;
973-
974 if (f->isExternal())
975 {
976 const xqtref_t& resType = f->getSignature().returnType();
977
978 resultExpr =
979- wrap_in_type_match(foExpr, resType, loc, TREAT_FUNC_RETURN, f->getName());
980+ wrap_in_type_match(resultExpr, resType, loc, TREAT_FUNC_RETURN, f->getName());
981 }
982
983 // Some further normalization is required for certain builtin functions
984@@ -11221,9 +11050,9 @@
985 case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_POINT_GENERAL_N:
986 case FunctionConsts::FN_ZORBA_XQDDF_PROBE_INDEX_RANGE_GENERAL_N:
987 {
988- resultExpr = CREATE(fo)(theRootSctx, theUDF, foExpr->get_loc(),
989+ resultExpr = CREATE(fo)(theRootSctx, theUDF, resultExpr->get_loc(),
990 BUILTIN_FUNC(OP_SORT_DISTINCT_NODES_ASC_1),
991- foExpr);
992+ resultExpr);
993
994 break;
995 }
996@@ -11231,7 +11060,7 @@
997 case FunctionConsts::FN_ANALYZE_STRING_3:
998 {
999 resultExpr =
1000- wrap_in_validate_expr_strict(foExpr, "http://www.w3.org/2005/xpath-functions");
1001+ wrap_in_validate_expr_strict(resultExpr, "http://www.w3.org/2005/xpath-functions");
1002
1003 break;
1004 }
1005@@ -11243,50 +11072,6 @@
1006
1007 break;
1008 }
1009- case FunctionConsts::FN_MAP_2:
1010- case FunctionConsts::FN_FILTER_2:
1011- {
1012- std::vector<expr*> args(foExpr->get_args());
1013- resultExpr = generate_fn_body(f, args, loc);
1014- break;
1015- }
1016- case FunctionConsts::FN_ZORBA_EVAL_1:
1017- case FunctionConsts::FN_ZORBA_EVAL_N_1:
1018- case FunctionConsts::FN_ZORBA_EVAL_U_1:
1019- case FunctionConsts::FN_ZORBA_EVAL_S_1:
1020- {
1021- expr_script_kind_t scriptKind;
1022-
1023- if (fKind == FunctionConsts::FN_ZORBA_EVAL_1 ||
1024- fKind == FunctionConsts::FN_ZORBA_EVAL_N_1)
1025- {
1026- scriptKind = SIMPLE_EXPR;
1027- }
1028- else if (fKind == FunctionConsts::FN_ZORBA_EVAL_U_1)
1029- {
1030- scriptKind = UPDATING_EXPR;
1031- }
1032- else
1033- {
1034- scriptKind = SEQUENTIAL_FUNC_EXPR;
1035- }
1036-
1037- eval_expr* evalExpr =
1038- CREATE(eval)(theRootSctx, theUDF, loc, foExpr->get_arg(0), scriptKind, theNSCtx);
1039-
1040- std::vector<VarInfo*> inscopeVars;
1041- theSctx->getVariables(inscopeVars);
1042-
1043- csize numVars = inscopeVars.size();
1044-
1045- for (csize i = 0; i < numVars; ++i)
1046- {
1047- evalExpr->add_var(inscopeVars[i]->getVar());
1048- }
1049-
1050- resultExpr = evalExpr;
1051- break;
1052- }
1053 case FunctionConsts::FN_ZORBA_INVOKE_N:
1054 case FunctionConsts::FN_ZORBA_INVOKE_N_N:
1055 case FunctionConsts::FN_ZORBA_INVOKE_U_N:
1056@@ -11446,9 +11231,15 @@
1057 std::vector<expr*>& arguments,
1058 const QueryLoc& loc)
1059 {
1060+ TypeManager* tm = CTX_TM;
1061+
1062 expr* resultExpr = NULL;
1063
1064- switch (f->getKind())
1065+ csize numArgs = arguments.size();
1066+
1067+ FunctionConsts::FunctionKind fkind = f->getKind();
1068+
1069+ switch (fkind)
1070 {
1071 case FunctionConsts::FN_POSITION_0:
1072 {
1073@@ -11460,6 +11251,66 @@
1074 resultExpr = lookup_ctx_var(LAST_IDX_VARNAME, loc);
1075 break;
1076 }
1077+ case FunctionConsts::FN_LANG_1:
1078+ {
1079+ arguments.push_back(DOT_REF);
1080+ f = BUILTIN_FUNC(FN_LANG_2);
1081+ break;
1082+ }
1083+ case FunctionConsts::FN_IDREF_1:
1084+ {
1085+ arguments.push_back(DOT_REF);
1086+ f = BUILTIN_FUNC(FN_IDREF_2);
1087+ break;
1088+ }
1089+ case FunctionConsts::FN_ID_1:
1090+ {
1091+ arguments.push_back(DOT_REF);
1092+ f = BUILTIN_FUNC(FN_ID_2);
1093+ resultExpr = generate_fn_body(f, arguments, loc);
1094+ break;
1095+ }
1096+ case FunctionConsts::FN_ELEMENT_WITH_ID_1:
1097+ {
1098+ arguments.push_back(DOT_REF);
1099+ f = BUILTIN_FUNC(FN_ELEMENT_WITH_ID_2);
1100+ resultExpr = generate_fn_body(f, arguments, loc);
1101+ break;
1102+ }
1103+ case FunctionConsts::FN_ID_2:
1104+ case FunctionConsts::FN_ELEMENT_WITH_ID_2:
1105+ {
1106+ expr* idsExpr = arguments[0];
1107+
1108+ flwor_expr* flworExpr = wrap_expr_in_flwor(idsExpr, false);
1109+
1110+ const for_clause* fc = static_cast<const for_clause*>(flworExpr->get_clause(0));
1111+ expr* flworVarExpr = fc->get_var();
1112+
1113+ fo_expr* normExpr = NULL;
1114+ fo_expr* tokenExpr = NULL;
1115+ zstring space(" ");
1116+ const_expr* constExpr = CREATE(const)(theRootSctx, theUDF, loc, space);
1117+
1118+ normExpr = CREATE(fo)(theRootSctx, theUDF, loc,
1119+ BUILTIN_FUNC(FN_NORMALIZE_SPACE_1),
1120+ flworVarExpr);
1121+ normalize_fo(normExpr);
1122+
1123+ tokenExpr = CREATE(fo)(theRootSctx, theUDF, loc,
1124+ BUILTIN_FUNC(FN_TOKENIZE_2),
1125+ normExpr,
1126+ constExpr);
1127+ normalize_fo(tokenExpr);
1128+
1129+ flworExpr->set_return_expr(tokenExpr);
1130+
1131+ pop_scope();
1132+
1133+ arguments[0] = flworExpr;
1134+
1135+ break;
1136+ }
1137 case FunctionConsts::FN_HEAD_1:
1138 {
1139 arguments.push_back(CREATE(const)(theRootSctx, theUDF, loc, xs_integer::one()));
1140@@ -11487,6 +11338,10 @@
1141 }
1142 case FunctionConsts::FN_NUMBER_1:
1143 {
1144+ // fn:number($arg) is translated as:
1145+ //
1146+ // let $v := data($arg) promote as xs:anyAtomicType?
1147+ // return if ($v castable as xs:double) then xs:double($v) else NaN
1148 var_expr* tv = create_temp_var(loc, var_expr::let_var);
1149
1150 expr* nanExpr = CREATE(const)(theRootSctx, theUDF, loc, xs_double::nan());
1151@@ -11520,6 +11375,133 @@
1152 theRTM.ANY_URI_TYPE_ONE, false);
1153 break;
1154 }
1155+ case FunctionConsts::FN_RESOLVE_URI_1:
1156+ {
1157+ zstring baseUri = theSctx->get_base_uri();
1158+ arguments.push_back(CREATE(const)(theRootSctx, theUDF, loc, baseUri));
1159+ f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
1160+
1161+ fo_expr* fo = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
1162+ normalize_fo(fo);
1163+ resultExpr = fo;
1164+
1165+ break;
1166+ }
1167+ case FunctionConsts::FN_SUBSEQUENCE_2:
1168+ case FunctionConsts::FN_SUBSEQUENCE_3:
1169+ case FunctionConsts::FN_SUBSTRING_2:
1170+ case FunctionConsts::FN_SUBSTRING_3:
1171+ {
1172+ if (numArgs == 2)
1173+ {
1174+ xqtref_t posType = arguments[1]->get_return_type();
1175+
1176+ if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc))
1177+ {
1178+ if (f->getKind() == FunctionConsts::FN_SUBSTRING_2)
1179+ f = BUILTIN_FUNC(OP_SUBSTRING_INT_2);
1180+ else
1181+ f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_2);
1182+ }
1183+ }
1184+ else
1185+ {
1186+ xqtref_t posType = arguments[1]->get_return_type();
1187+ xqtref_t lenType = arguments[2]->get_return_type();
1188+
1189+ if (TypeOps::is_subtype(tm, *posType, *theRTM.INTEGER_TYPE_STAR, loc) &&
1190+ TypeOps::is_subtype(tm, *lenType, *theRTM.INTEGER_TYPE_STAR, loc))
1191+ {
1192+ if (f->getKind() == FunctionConsts::FN_SUBSTRING_3)
1193+ f = BUILTIN_FUNC(OP_SUBSTRING_INT_3);
1194+ else
1195+ f = BUILTIN_FUNC(OP_ZORBA_SUBSEQUENCE_INT_3);
1196+ }
1197+ }
1198+
1199+ break;
1200+ }
1201+ case FunctionConsts::FN_CONCAT_N:
1202+ {
1203+ if (numArgs < 2)
1204+ {
1205+ RAISE_ERROR(err::XPST0017, loc,
1206+ ERROR_PARAMS("concat", ZED(FunctionUndeclared_3), numArgs));
1207+ }
1208+ break;
1209+ }
1210+ case FunctionConsts::FN_DOC_1:
1211+ {
1212+ //validate uri, if known
1213+ expr* doc_uri = arguments[0];
1214+
1215+ if (doc_uri->get_expr_kind() == const_expr_kind)
1216+ {
1217+ const_expr* const_uri = reinterpret_cast<const_expr*>(doc_uri);
1218+ const store::Item* uri_value = const_uri->get_val();
1219+ zstring uri_string = uri_value->getStringValue();
1220+
1221+ try
1222+ {
1223+ if (uri_string.find(":/", 0, 3) != zstring::npos)
1224+ {
1225+ URI docURI(uri_string, true);//with validate
1226+ }
1227+ }
1228+ catch(XQueryException& e)
1229+ {
1230+ set_source(e, loc);
1231+ throw;
1232+ }
1233+ }
1234+ break;
1235+ }
1236+ case FunctionConsts::FN_ZORBA_EVAL_1:
1237+ case FunctionConsts::FN_ZORBA_EVAL_N_1:
1238+ case FunctionConsts::FN_ZORBA_EVAL_U_1:
1239+ case FunctionConsts::FN_ZORBA_EVAL_S_1:
1240+ {
1241+ expr_script_kind_t scriptKind;
1242+
1243+ if (fkind == FunctionConsts::FN_ZORBA_EVAL_1 ||
1244+ fkind == FunctionConsts::FN_ZORBA_EVAL_N_1)
1245+ {
1246+ scriptKind = SIMPLE_EXPR;
1247+ }
1248+ else if (fkind == FunctionConsts::FN_ZORBA_EVAL_U_1)
1249+ {
1250+ scriptKind = UPDATING_EXPR;
1251+ }
1252+ else
1253+ {
1254+ scriptKind = SEQUENTIAL_FUNC_EXPR;
1255+ }
1256+
1257+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
1258+
1259+ eval_expr* evalExpr =
1260+ CREATE(eval)(theRootSctx, theUDF, loc, arguments[0], scriptKind, theNSCtx);
1261+
1262+ std::vector<VarInfo*> inscopeVars;
1263+ theSctx->getVariables(inscopeVars);
1264+
1265+ csize numVars = inscopeVars.size();
1266+
1267+ for (csize i = 0; i < numVars; ++i)
1268+ {
1269+ evalExpr->add_var(inscopeVars[i]->getVar());
1270+ }
1271+
1272+ resultExpr = evalExpr;
1273+ break;
1274+ }
1275+ case FunctionConsts::FN_FOLD_RIGHT_3:
1276+ {
1277+ arguments[2] = CREATE(fo)(theRootSctx, theUDF, loc,
1278+ BUILTIN_FUNC(FN_REVERSE_1),
1279+ arguments[2]);
1280+ break;
1281+ }
1282 case FunctionConsts::FN_MAP_2:
1283 {
1284 // map(function, sequence) is rewritten internally as:
1285@@ -11527,6 +11509,8 @@
1286 // for $item in $sequence
1287 // return dynamic_function_invocation[ $function, $item ]
1288
1289+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
1290+
1291 flwor_expr* flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
1292 for_clause* seq_fc = wrap_in_forclause(arguments[1], false);
1293 flwor->add_clause(seq_fc);
1294@@ -11555,6 +11539,8 @@
1295 // then $item
1296 // else ()
1297
1298+ arguments[0] = normalize_fo_arg(0, arguments[0], f, loc);
1299+
1300 flwor_expr* flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
1301 for_clause* seq_fc = wrap_in_forclause(arguments[1], true);
1302 flwor->add_clause(seq_fc);
1303@@ -11586,10 +11572,18 @@
1304 }
1305 default:
1306 {
1307- ZORBA_ASSERT(false);
1308+ break;
1309 }
1310 } // switch (lKind)
1311
1312+ if (resultExpr == NULL)
1313+ {
1314+ fo_expr* foExpr = CREATE(fo)(theRootSctx, theUDF, loc, f, arguments);
1315+ normalize_fo(foExpr);
1316+
1317+ resultExpr = foExpr;
1318+ }
1319+
1320 return resultExpr;
1321 }
1322
1323@@ -11791,6 +11785,7 @@
1324 {
1325 xqtref_t type;
1326 user_function* udf = NULL;
1327+ expr* body;
1328 bool needs_context_item = false;
1329
1330 // Get function implementation
1331@@ -11800,14 +11795,13 @@
1332 // function
1333 if (f == NULL)
1334 {
1335- type = CTX_TM->create_named_type(qnameItem,
1336- TypeConstants::QUANT_QUESTION,
1337- loc);
1338+ type = CTX_TM->
1339+ create_named_type(qnameItem, TypeConstants::QUANT_QUESTION, loc);
1340
1341 if (type == NULL ||
1342 arity != 1 ||
1343- TypeOps::is_equal(CTX_TM, *type, *GENV_TYPESYSTEM.NOTATION_TYPE_QUESTION, loc) ||
1344- TypeOps::is_equal(CTX_TM, *type, *GENV_TYPESYSTEM.ANY_ATOMIC_TYPE_QUESTION, loc))
1345+ TypeOps::is_equal(CTX_TM, *type, *theRTM.NOTATION_TYPE_QUESTION, loc) ||
1346+ TypeOps::is_equal(CTX_TM, *type, *theRTM.ANY_ATOMIC_TYPE_QUESTION, loc))
1347 {
1348 RAISE_ERROR(err::XPST0017, loc,
1349 ERROR_PARAMS(qnameItem->getStringValue(), ZED(FunctionUndeclared_3), arity));
1350@@ -11826,7 +11820,6 @@
1351 theCCB);
1352
1353 udf->setArgVars(udfArgs);
1354- udf->setOptimized(true);
1355 f = udf;
1356 }
1357 else
1358@@ -11870,19 +11863,19 @@
1359 // in a udf UF: function UF(x1 as T1, ..., xN as TN) as R { F(x1, ... xN) }
1360 if (!f->isUdf())
1361 {
1362- FunctionConsts::FunctionKind fKind = f->getKind();
1363+ FunctionConsts::FunctionKind fkind = f->getKind();
1364
1365- // Add context-item for functions with zero arguments which implicitly
1366- // take the context-item as argument
1367- if (xquery_fns_def_dot.test(fKind) ||
1368- fKind == FunctionConsts::FN_LANG_1 ||
1369- fKind == FunctionConsts::FN_ID_1 ||
1370- fKind == FunctionConsts::FN_ELEMENT_WITH_ID_1 ||
1371- fKind == FunctionConsts::FN_IDREF_1)
1372+ // Add context-item for functions which implicitly access the context-item
1373+ if (xquery_fns_def_dot.test(fkind) ||
1374+ fkind == FunctionConsts::FN_LANG_1 ||
1375+ fkind == FunctionConsts::FN_IDREF_1 ||
1376+ fkind == FunctionConsts::FN_ID_1 ||
1377+ fkind == FunctionConsts::FN_ELEMENT_WITH_ID_1)
1378 {
1379 arity++;
1380 f = theSctx->lookup_fn(qnameItem, arity, loc);
1381 needs_context_item = true;
1382+ fkind = f->getKind();
1383 }
1384
1385 udf = new user_function(loc,
1386@@ -11902,47 +11895,21 @@
1387 foArgs[i] = argVar;
1388 }
1389
1390- expr* body;
1391+ switch (fkind)
1392+ {
1393 // process pure builtin functions that have no associated iterator
1394- switch (f->getKind())
1395- {
1396- case FunctionConsts::FN_NUMBER_1:
1397 case FunctionConsts::FN_HEAD_1:
1398 case FunctionConsts::FN_TAIL_1:
1399+ case FunctionConsts::FN_NUMBER_1:
1400+ case FunctionConsts::FN_STATIC_BASE_URI_0:
1401+ case FunctionConsts::FN_RESOLVE_URI_1:
1402+ case FunctionConsts::FN_ID_2:
1403+ case FunctionConsts::FN_ELEMENT_WITH_ID_2:
1404+ case FunctionConsts::FN_FOLD_RIGHT_3:
1405 case FunctionConsts::FN_MAP_2:
1406 case FunctionConsts::FN_FILTER_2:
1407- case FunctionConsts::FN_STATIC_BASE_URI_0:
1408- {
1409- // create the function flwor, wrap params in for clauses
1410- flwor_expr* flwor = CREATE(flwor)(theSctx, theUDF, loc, false);
1411- std::vector<expr*> arguments;
1412- for (csize i = 0; i < foArgs.size(); i++)
1413- {
1414- let_clause* lc = wrap_in_letclause(&*udfArgs[i]); // FN_HEAD and FN_TAIL need this to be a LET clause
1415- udfArgs[i]->set_param_pos(flwor->num_clauses());
1416- flwor->add_clause(lc);
1417- arguments.push_back(lc->get_var());
1418- }
1419-
1420- flwor->set_return_expr(generate_fn_body(f, arguments, loc));
1421-
1422- body = flwor;
1423-
1424- if (flwor->num_clauses() == 0)
1425- body = flwor->get_return_expr();
1426-
1427- break;
1428- }
1429- case FunctionConsts::FN_RESOLVE_URI_1:
1430- {
1431- zstring baseUri = theSctx->get_base_uri();
1432- foArgs.push_back(CREATE(const)(theRootSctx, theUDF, loc, baseUri));
1433- f = BUILTIN_FUNC(FN_RESOLVE_URI_2);
1434-
1435- fo_expr* fo = CREATE(fo)(theRootSctx, udf, loc, f, foArgs);
1436- normalize_fo(fo);
1437-
1438- body = fo;
1439+ {
1440+ body = generate_fn_body(f, foArgs, loc);
1441 break;
1442 }
1443 default:
1444@@ -11957,23 +11924,18 @@
1445
1446 udf->setArgVars(udfArgs);
1447 udf->setBody(body);
1448- udf->setOptimized(true); // TODO: this is needed because otherwise the optimizer would get into an infinte cycle
1449
1450 f = udf;
1451 } // if builtin function
1452 }
1453
1454- static_context* closureSctx = theRootSctx->create_child_context();
1455- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
1456-
1457 expr* fiExpr = CREATE(function_item)(theRootSctx, theUDF, loc,
1458- closureSctx,
1459 f,
1460 f->getName(),
1461 arity,
1462- false,
1463+ false, // not inline
1464 needs_context_item,
1465- false);
1466+ false); // not coersion
1467
1468 return fiExpr;
1469 }
1470@@ -11994,16 +11956,13 @@
1471
1472 push_scope();
1473
1474- static_context* closureSctx = theRootSctx->create_child_context();
1475- theCCB->theSctxMap[theCCB->theSctxMap.size() + 1] = closureSctx;
1476-
1477 function_item_expr* fiExpr =
1478- CREATE(function_item)(theRootSctx, theUDF, loc, closureSctx, true, false, false);
1479+ CREATE(function_item)(theRootSctx, theUDF, loc, true, false, false);
1480
1481 push_nodestack(fiExpr);
1482
1483 // Translate the return tyoe
1484- xqtref_t returnType = GENV_TYPESYSTEM.ITEM_TYPE_STAR;
1485+ xqtref_t returnType = theRTM.ITEM_TYPE_STAR;
1486 if (v.getReturnType() != 0)
1487 {
1488 v.getReturnType()->accept(*this);
1489@@ -12023,7 +11982,7 @@
1490 const SequenceType* paramType = param->get_typedecl();
1491 if (paramType == 0)
1492 {
1493- paramTypes.push_back(GENV_TYPESYSTEM.ITEM_TYPE_STAR);
1494+ paramTypes.push_back(theRTM.ITEM_TYPE_STAR);
1495 }
1496 else
1497 {
1498@@ -12050,7 +12009,7 @@
1499 }
1500 else
1501 {
1502- flwor = theExprManager->create_flwor_expr(theRootSctx, theUDF, loc, false);
1503+ flwor = CREATE(flwor)(theRootSctx, theUDF, loc, false);
1504 }
1505
1506 // Handle inscope variables. For each inscope var, a let binding is added to
1507
1508=== modified file 'src/runtime/function_item/function_item.cpp'
1509--- src/runtime/function_item/function_item.cpp 2013-03-17 15:07:49 +0000
1510+++ src/runtime/function_item/function_item.cpp 2013-03-23 15:26:22 +0000
1511@@ -64,8 +64,8 @@
1512 bool isCoercion)
1513 :
1514 theMustDeleteCCB(false),
1515+ theLoc(loc),
1516 theClosureSctx(closureSctx),
1517- theLoc(loc),
1518 theFunction(func),
1519 theQName(qname),
1520 theArity(arity),
1521@@ -249,14 +249,10 @@
1522 }
1523 }
1524
1525-// if (theDynamicFunctionInfo->theCCB != NULL)
1526-// ccb = theDynamicFunctionInfo->theCCB;
1527-
1528 expr* dummy = ccb->theEM->
1529 create_function_item_expr(NULL,
1530 NULL,
1531 theDynamicFunctionInfo->theLoc,
1532- NULL,
1533 false,
1534 false,
1535 false);
1536
1537=== modified file 'src/runtime/function_item/function_item.h'
1538--- src/runtime/function_item/function_item.h 2013-03-17 14:11:09 +0000
1539+++ src/runtime/function_item/function_item.h 2013-03-23 15:26:22 +0000
1540@@ -44,7 +44,71 @@
1541 theMustDeleteCCB :
1542 ------------------
1543 This is set to true if the DynamicFunctionInfo is the owner of the CCB,
1544- and must delete it upon destruction.
1545+ and must delete it upon destruction.
1546+
1547+ theLoc:
1548+ -------
1549+ The location where the function item expr or inline function expr appear at.
1550+
1551+ theClosureSctx:
1552+ ---------------
1553+ The static context to be used when the function item is actually invoked.
1554+
1555+ theFunction:
1556+ ------------
1557+ The function obj that represents the implementation of this function item.
1558+ This is always a pointer to a user_function obj. In case of an inline function
1559+ expr, it is an anonymous user_function obj that is created on-the-fly by the
1560+ translator to represent the body and signature of the inline function. In case
1561+ of a function item expr where the named function is a UDF, it is the
1562+ user_function obj of that UDF. Finally, in case of a function item expr where
1563+ the named function F is not a UDF, it is a user_function obj UF that is created
1564+ on-the-fly by the translator. The signature of UF is the same as that of F, and
1565+ its body simply invokes F. The reason why UF is built is to unify the
1566+ implemenation of dynamic function invocation.
1567+
1568+ theQName:
1569+ ---------
1570+
1571+ theArity:
1572+ ---------
1573+ We need to store the arity also here because the function obj above doesn't
1574+ know about its arity in case it's a variadic function.
1575+
1576+ theIsInline:
1577+ ------------
1578+
1579+ theNeedsContextItem:
1580+ --------------------
1581+ Whether the function is a contextual one, i.e., accesses the context item, or
1582+ context position, or context size directly.
1583+
1584+ theIsCoercion:
1585+ --------------
1586+ This is set to true if the function item is a function coercion. In this
1587+ case the newly created function item's name is taken from the coerced
1588+ function.
1589+
1590+ theScopedVarsValues:
1591+ --------------------
1592+ Empty in the case of LiteralFunctionItem. Otherwise, the vars that are in
1593+ scope at the place where the InlineFunction expr appears at.
1594+
1595+ theSubstVarsValues:
1596+ -------------------
1597+
1598+ theScopedVarsNames:
1599+ -------------------
1600+
1601+ theIsGlobalVar:
1602+ ---------------
1603+
1604+ theVarId:
1605+ ---------
1606+
1607+ theScopedVarsIteratosr:
1608+ -----------------------
1609+
1610 ********************************************************************************/
1611 class DynamicFunctionInfo : public SimpleRCObject
1612 {
1613@@ -52,16 +116,14 @@
1614 CompilerCB * theCCB;
1615 bool theMustDeleteCCB;
1616
1617+ QueryLoc theLoc;
1618 static_context * theClosureSctx;
1619- QueryLoc theLoc;
1620 function_t theFunction;
1621 store::Item_t theQName;
1622 unsigned int theArity;
1623 bool theIsInline;
1624 bool theNeedsContextItem;
1625- bool theIsCoercion; // This is set to true if the function item is a function coercion. In this
1626- // case the newly created function item's name is taken from the coerced
1627- // function.
1628+ bool theIsCoercion;
1629
1630 std::vector<expr*> theScopedVarsValues;
1631 std::vector<var_expr*> theSubstVarsValues;
1632@@ -102,7 +164,6 @@
1633 /*******************************************************************************
1634 A FunctionItem is created during codegen, when a function_item_expr is reached.
1635
1636- theCCB :
1637 theSctx : The static context of the function_item_expr.
1638 theExpr : The associated function_item_expr.
1639 theVariableValues : Vector of var iterators representing the values of the
1640@@ -129,8 +190,9 @@
1641 void serialize(::zorba::serialization::Archiver& ar);
1642
1643 public:
1644- FunctionItem(const DynamicFunctionInfo_t& dynamicFunctionInfo,
1645- dynamic_context* dctx);
1646+ FunctionItem(
1647+ const DynamicFunctionInfo_t& dynamicFunctionInfo,
1648+ dynamic_context* dctx);
1649
1650 SYNC_CODE(RCLock* getRCLock() const { return &theRCLock; })
1651
1652
1653=== modified file 'test/fots/CMakeLists.txt'
1654--- test/fots/CMakeLists.txt 2013-03-22 04:37:29 +0000
1655+++ test/fots/CMakeLists.txt 2013-03-23 15:26:22 +0000
1656@@ -641,7 +641,6 @@
1657 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-376 0)
1658 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-402 0)
1659 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-404 0)
1660-EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-430 0)
1661 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-494 0)
1662 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-523 0)
1663 EXPECTED_FOTS_FAILURE (fn-function-lookup fn-function-lookup-524 0)
1664@@ -682,7 +681,6 @@
1665 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-376 0)
1666 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-402 0)
1667 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-404 0)
1668-EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-430 0)
1669 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-494 0)
1670 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-523 0)
1671 EXPECTED_FOTS_FAILURE (prod-NamedFunctionRef function-literal-524 0)

Subscribers

People subscribed via source and target branches