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