1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "stdafx.h"
17 
18 #include <vector>
19 
20 #include "context/static_context.h"
21 
22 #include "runtime/maths/maths.h"
23 
24 #include "types/casting.h"
25 #include "types/typeconstants.h"
26 #include "types/typeops.h"
27 
28 #include "system/globalenv.h"
29 #include "store/api/item_factory.h"
30 #include "store/api/item.h"
31 
32 #include "diagnostics/xquery_diagnostics.h"
33 #include "zorbatypes/numconversions.h"
34 
35 namespace zorba {
36 
37 //math:sqrt
38 bool
nextImpl(store::Item_t & result,PlanState & planState) const39 SqrtIterator::nextImpl (store::Item_t& result, PlanState& planState) const
40 {
41   store::Item_t item;
42   xqtref_t type;
43 
44   PlanIteratorState* state;
45   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
46 
47   if (consumeNext(result, theChild.getp(), planState ))
48   {
49     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().sqrt());
50 
51     STACK_PUSH (true, state);
52   }
53   STACK_END (state);
54 }
55 
56 //math:exp
57 bool
nextImpl(store::Item_t & result,PlanState & planState) const58 ExpIterator::nextImpl (store::Item_t& result, PlanState& planState) const
59 {
60   PlanIteratorState* state;
61   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
62 
63   if (consumeNext(result, this->theChild.getp(), planState ))
64   {
65     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().exp());
66     STACK_PUSH (true, state);
67   }
68   STACK_END (state);
69 }
70 
71 //math:exp10
72 
73 bool
nextImpl(store::Item_t & result,PlanState & planState) const74 Exp10Iterator::nextImpl (store::Item_t& result, PlanState& planState) const
75 {
76   PlanIteratorState* state;
77   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
78 
79   if (consumeNext(result, this->theChild.getp(), planState ))
80   {
81     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().exp10());
82     STACK_PUSH (true, state);
83   }
84   STACK_END (state);
85 }
86 
87 
88 //math:log
89 bool
nextImpl(store::Item_t & result,PlanState & planState) const90 LogIterator::nextImpl (store::Item_t& result, PlanState& planState) const
91 {
92   PlanIteratorState* state;
93   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
94 
95   if (consumeNext(result, this->theChild.getp(), planState ))
96   {
97     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().log());
98     STACK_PUSH (true, state);
99   }
100   STACK_END (state);
101 }
102 
103 //math:log10
104 bool
nextImpl(store::Item_t & result,PlanState & planState) const105 Log10Iterator::nextImpl (store::Item_t& result, PlanState& planState) const
106 {
107   PlanIteratorState* state;
108   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
109 
110   if (consumeNext(result, this->theChild.getp(), planState ))
111   {
112     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().log10());
113     STACK_PUSH (true, state);
114   }
115   STACK_END (state);
116 }
117 
118 //math:sin
119 bool
nextImpl(store::Item_t & result,PlanState & planState) const120 SinIterator::nextImpl (store::Item_t& result, PlanState& planState) const
121 {
122   PlanIteratorState* state;
123   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
124 
125   if (consumeNext(result, this->theChild.getp(), planState ))
126   {
127     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().sin());
128     STACK_PUSH (true, state);
129   }
130   STACK_END (state);
131 }
132 
133 //math:cos
134 bool
nextImpl(store::Item_t & result,PlanState & planState) const135 CosIterator::nextImpl (store::Item_t& result, PlanState& planState) const
136 {
137   PlanIteratorState* state;
138   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
139 
140   if (consumeNext(result, this->theChild.getp(), planState ))
141   {
142     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().cos());
143     STACK_PUSH (true, state);
144   }
145   STACK_END (state);
146 }
147 
148 //math:tan
149 bool
nextImpl(store::Item_t & result,PlanState & planState) const150 TanIterator::nextImpl (store::Item_t& result, PlanState& planState) const
151 {
152   PlanIteratorState* state;
153   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
154 
155   if (consumeNext(result, this->theChild.getp(), planState ))
156   {
157     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().tan());
158     STACK_PUSH (true, state);
159   }
160   STACK_END (state);
161 }
162 
163 //math:asin
164 bool
nextImpl(store::Item_t & result,PlanState & planState) const165 ArcSinIterator::nextImpl (store::Item_t& result, PlanState& planState) const
166 {
167   PlanIteratorState* state;
168   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
169 
170   if (consumeNext(result, this->theChild.getp(), planState ))
171   {
172     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().asin());
173     STACK_PUSH (true, state);
174   }
175   STACK_END (state);
176 }
177 
178 //math:acos
179 bool
nextImpl(store::Item_t & result,PlanState & planState) const180 ArcCosIterator::nextImpl (store::Item_t& result, PlanState& planState) const
181 {
182   PlanIteratorState* state;
183   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
184 
185   if (consumeNext(result, this->theChild.getp(), planState ))
186   {
187     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().acos());
188     STACK_PUSH (true, state);
189   }
190   STACK_END (state);
191 }
192 
193 //math:atan
194 bool
nextImpl(store::Item_t & result,PlanState & planState) const195 ArcTanIterator::nextImpl (store::Item_t& result, PlanState& planState) const
196 {
197   PlanIteratorState* state;
198   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
199 
200   if (consumeNext(result, this->theChild.getp(), planState ))
201   {
202     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().atan());
203     STACK_PUSH (true, state);
204   }
205   STACK_END (state);
206 }
207 
208 //math:atan2
209 bool
nextImpl(store::Item_t & result,PlanState & planState) const210 Atan2Iterator::nextImpl (store::Item_t& result, PlanState& planState) const
211 {
212   store::Item_t n0;
213   store::Item_t n1;
214   xs_double doub1;
215   xs_double doub2;
216 
217   PlanIteratorState* state;
218   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
219 
220   if (!consumeNext(n0, this->theChild0.getp(), planState))
221     ZORBA_ASSERT(false);
222 
223   if (!consumeNext(n1, this->theChild1.getp(), planState))
224     ZORBA_ASSERT(false);
225 
226   doub1 = n0->getDoubleValue();
227   doub2 = n1->getDoubleValue();
228 
229   GENV_ITEMFACTORY->createDouble(result, doub1.atan2(doub2));
230 
231   STACK_PUSH(true, state);
232 
233   STACK_END(state);
234 }
235 
236 //math:cosh
237 bool
nextImpl(store::Item_t & result,PlanState & planState) const238 CoshIterator::nextImpl (store::Item_t& result, PlanState& planState) const
239 {
240   PlanIteratorState* state;
241   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
242 
243   if (consumeNext(result, theChild.getp(), planState ))
244   {
245     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().cosh());
246     STACK_PUSH (true, state);
247   }
248   STACK_END (state);
249 }
250 
251 //math:acosh
252 bool
nextImpl(store::Item_t & result,PlanState & planState) const253 AcoshIterator::nextImpl (store::Item_t& result, PlanState& planState) const
254 {
255   PlanIteratorState* state;
256   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
257 
258   if (consumeNext(result, theChild.getp(), planState ))
259   {
260     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().acosh());
261     STACK_PUSH (true, state);
262   }
263   STACK_END (state);
264 }
265 
266 //fmod
267 bool
nextImpl(store::Item_t & result,PlanState & planState) const268 FmodIterator::nextImpl (store::Item_t& result, PlanState& planState) const
269 {
270   store::Item_t n0;
271   store::Item_t n1;
272 
273   PlanIteratorState* state;
274   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
275 
276   if (consumeNext(n0, this->theChild0.getp(), planState))
277   {
278     if (consumeNext(n1, this->theChild1.getp(), planState))
279     {
280       {
281         xs_double doub1 = n0->getDoubleValue();
282         xs_double doub2 = n1->getDoubleValue();
283 
284         GENV_ITEMFACTORY->createDouble(result, doub1.fmod(doub2));
285       }
286 
287       if (consumeNext(n0, this->theChild0.getp(), planState) ||
288           consumeNext(n1, this->theChild1.getp(), planState))
289         throw XQUERY_EXCEPTION(
290           err::XPTY0004, ERROR_PARAMS( ZED( NoSeqForFnOp_2 ), "fmod" )
291         );
292       STACK_PUSH(true, state);
293     }
294   }
295 
296   STACK_END(state);
297 }
298 
299 //math:ldexp
300 bool
nextImpl(store::Item_t & result,PlanState & planState) const301 LdexpIterator::nextImpl (store::Item_t& result, PlanState& planState) const
302 {
303   store::Item_t n0;
304   store::Item_t n1;
305 
306   PlanIteratorState* state;
307   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
308 
309   if (consumeNext(n0, this->theChild0.getp(), planState))
310   {
311     if (consumeNext(n1, this->theChild1.getp(), planState))
312     {
313       {
314         xs_integer integ = n1->getIntegerValue();
315         xs_double  doub = n0->getDoubleValue();
316         xs_integer integ_2(2);
317         xs_double doub_pow = integ_2.pow(integ);
318 
319         GENV_ITEMFACTORY->createDouble(result, doub * doub_pow);
320       }
321 
322       if (consumeNext(n0, this->theChild0.getp(), planState) ||
323           consumeNext(n1, this->theChild1.getp(), planState))
324         throw XQUERY_EXCEPTION(
325           err::XPTY0004, ERROR_PARAMS( ZED( NoSeqForFnOp_2 ), "ldexp" )
326         );
327       STACK_PUSH(true, state);
328     }
329   }
330 
331   STACK_END(state);
332 }
333 
334 //math:pow
335 bool
nextImpl(store::Item_t & result,PlanState & planState) const336 PowIterator::nextImpl(store::Item_t& result, PlanState& planState) const
337 {
338   store::Item_t n0;
339   store::Item_t n1;
340 
341   PlanIteratorState* state;
342   DEFAULT_STACK_INIT(PlanIteratorState, state, planState);
343 
344   if (consumeNext(n0, this->theChild0.getp(), planState))
345   {
346     if (consumeNext(n1, this->theChild1.getp(), planState))
347     {
348       {
349         xqtref_t type;
350 
351         const TypeManager* tm = theSctx->get_typemanager();
352 
353         const RootTypeManager& rtm = GENV_TYPESYSTEM;
354         xs_double doub1 = n0->getDoubleValue();
355         //xs_double  doub2 = n1->getDoubleValue();
356 
357         //GENV_ITEMFACTORY->createDouble(result, doub1.pow(doub2));
358 
359         assert(n1->isAtomic());
360 
361         type = tm->create_value_type(n1);
362 
363         if (TypeOps::is_subtype(tm, *type, *rtm.UNTYPED_ATOMIC_TYPE_ONE))
364         {
365           GenericCast::castToAtomic(result, result, &*rtm.DOUBLE_TYPE_ONE, tm, NULL, loc);
366           type = tm->create_value_type(result);
367         }
368 
369         if (TypeOps::is_subtype(tm, *type, *rtm.DOUBLE_TYPE_ONE))
370         {
371           GENV_ITEMFACTORY->createDouble(result, doub1.pow(n1->getDoubleValue()));
372         }
373         else if (TypeOps::is_subtype(tm, *type, *rtm.FLOAT_TYPE_ONE))
374         {
375           store::Item_t n1_double;
376           GenericCast::castToAtomic(n1_double,
377                                     n1,
378                                     rtm.DOUBLE_TYPE_ONE.getp(),
379                                     tm,
380                                     NULL,
381                                     loc);
382 
383           GENV_ITEMFACTORY->createDouble(result, doub1.pow(n1_double->getDoubleValue()));
384         }
385         else if (TypeOps::is_subtype(tm, *type, *rtm.INTEGER_TYPE_ONE))
386         {
387           xs_integer n1_integer = n1->getIntegerValue();
388           try
389           {
390             xs_int const n1_int = to_xs_int(n1_integer);
391             GENV_ITEMFACTORY->createDouble(result, doub1.pow(n1_int));
392           }
393           catch ( std::range_error const& )
394           {
395             throw XQUERY_EXCEPTION(
396               err::XPTY0004,
397               ERROR_PARAMS( ZED( NoCastToCInt_2 ), n1_integer ),
398               ERROR_LOC( loc )
399             );
400           }
401         }
402         else if (TypeOps::is_subtype(tm, *type, *rtm.DECIMAL_TYPE_ONE))
403         {
404           store::Item_t n1_double;
405           GenericCast::castToAtomic(n1_double,
406                                     n1,
407                                     rtm.DOUBLE_TYPE_ONE.getp(),
408                                     tm,
409                                     NULL,
410                                     loc);
411 
412           GENV_ITEMFACTORY->createDouble(result, doub1.pow(n1_double->getDoubleValue()));
413         }
414         else
415         {
416           throw XQUERY_EXCEPTION(
417             err::XPTY0004,
418             ERROR_PARAMS( ZED( BadTypeFor_23 ), type, "math:pow" ),
419             ERROR_LOC( loc )
420           );
421         }
422       }
423 
424       if (consumeNext(n0, this->theChild0.getp(), planState) ||
425           consumeNext(n1, this->theChild1.getp(), planState))
426         throw XQUERY_EXCEPTION(
427           err::XPTY0004, ERROR_PARAMS( ZED( NoSeqForFnOp_2 ), "math:pow" )
428         );
429       STACK_PUSH(true, state);
430     }
431   }
432 
433   STACK_END(state);
434 }
435 
436 //math:sinh
437 bool
nextImpl(store::Item_t & result,PlanState & planState) const438 SinhIterator::nextImpl (store::Item_t& result, PlanState& planState) const
439 {
440   PlanIteratorState* state;
441   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
442 
443   if (consumeNext(result, theChild.getp(), planState ))
444   {
445     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().sinh());
446     STACK_PUSH (true, state);
447   }
448   STACK_END (state);
449 }
450 
451 //math:asinh
452 bool
nextImpl(store::Item_t & result,PlanState & planState) const453 AsinhIterator::nextImpl (store::Item_t& result, PlanState& planState) const
454 {
455   PlanIteratorState* state;
456   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
457 
458   if (consumeNext(result, theChild.getp(), planState ))
459   {
460     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().asinh());
461     STACK_PUSH (true, state);
462   }
463   STACK_END (state);
464 }
465 
466 //math:tanh
467 bool
nextImpl(store::Item_t & result,PlanState & planState) const468 TanhIterator::nextImpl (store::Item_t& result, PlanState& planState) const
469 {
470   PlanIteratorState* state;
471   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
472 
473   if (consumeNext(result, theChild.getp(), planState ))
474   {
475     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().tanh());
476     STACK_PUSH (true, state);
477   }
478   STACK_END (state);
479 }
480 
481 //math:atanh
482 bool
nextImpl(store::Item_t & result,PlanState & planState) const483 AtanhIterator::nextImpl (store::Item_t& result, PlanState& planState) const
484 {
485   PlanIteratorState* state;
486   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
487 
488   if (consumeNext(result, theChild.getp(), planState ))
489   {
490     GENV_ITEMFACTORY->createDouble(result, result->getDoubleValue().atanh());
491     STACK_PUSH (true, state);
492   }
493   STACK_END (state);
494 }
495 
496 //math:pi
497 bool
nextImpl(store::Item_t & result,PlanState & planState) const498 PiNumberIterator::nextImpl (store::Item_t& result, PlanState& planState) const
499 {
500   PlanIteratorState* state;
501   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
502 
503   GENV_ITEMFACTORY->createDouble(result, xs_double(3.141592653589793e0));
504   STACK_PUSH (true, state);
505 
506   STACK_END (state);
507 }
508 
509 //math:isInf
510 bool
nextImpl(store::Item_t & result,PlanState & planState) const511 IsInfIterator::nextImpl (store::Item_t& result, PlanState& planState) const
512 {
513   PlanIteratorState* state;
514   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
515 
516   if (consumeNext(result, theChild.getp(), planState ))
517   {
518     GENV_ITEMFACTORY->createBoolean(result, !result->getDoubleValue().isFinite());
519     STACK_PUSH (true, state);
520   }
521   STACK_END (state);
522 }
523 
524 //math:isNaN
525 bool
nextImpl(store::Item_t & result,PlanState & planState) const526 IsNaNIterator::nextImpl (store::Item_t& result, PlanState& planState) const
527 {
528   PlanIteratorState* state;
529   DEFAULT_STACK_INIT ( PlanIteratorState, state, planState );
530 
531   if (consumeNext(result, theChild.getp(), planState ))
532   {
533     GENV_ITEMFACTORY->createBoolean(result, result->getDoubleValue().isNaN());
534     STACK_PUSH (true, state);
535   }
536   STACK_END (state);
537 }
538 
539 //math:modf
540 bool
nextImpl(store::Item_t & result,PlanState & planState) const541 ModfIterator::nextImpl (store::Item_t& result, PlanState& planState) const
542 {
543   ModfIteratorState* state;
544   DEFAULT_STACK_INIT ( ModfIteratorState, state, planState );
545 
546   if (consumeNext(result, theChild.getp(), planState ))
547   {
548     {
549       xs_double    doub = result->getDoubleValue();
550       xs_double    doub_fraction;
551       doub.modf(doub_fraction, state->theDoubInteger);
552       GENV_ITEMFACTORY->createDouble(result, doub_fraction);
553     }
554     STACK_PUSH (true, state);
555     GENV_ITEMFACTORY->createDouble(result, state->theDoubInteger);
556     STACK_PUSH (true, state);
557   }
558   STACK_END (state);
559 }
560 
561 //math:frexp
562 bool
nextImpl(store::Item_t & result,PlanState & planState) const563 FrexpIterator::nextImpl (store::Item_t& result, PlanState& planState) const
564 {
565   FrexpIteratorState* state;
566   DEFAULT_STACK_INIT ( FrexpIteratorState, state, planState );
567 
568   if (consumeNext(result, theChild.getp(), planState ))
569   {
570     {
571       xs_double    doub = result->getDoubleValue();
572       xs_double    doub_mantissa;
573       doub.frexp(doub_mantissa, state->theIntExponent);
574       GENV_ITEMFACTORY->createDouble(result, doub_mantissa);
575     }
576     STACK_PUSH (true, state);
577     GENV_ITEMFACTORY->createInteger(result, state->theIntExponent);
578     STACK_PUSH (true, state);
579   }
580   STACK_END (state);
581 }
582 } // namespace zorba
583 /* vim:set et sw=2 ts=2: */
584