1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2014, 2015 Henrik Tidefelt
21 #include "Shapes_Helpers_decls.h"
23 #include "shapescore.h"
26 #include "shapesexceptions.h"
28 #include "simplepdfi.h"
29 #include "autoonoff.h"
40 /* Use definition from stdlib.h */
41 #define RANDOM_MAX RAND_MAX
42 #define TWO_DIV_RANDOM_MAX (2. / RAND_MAX)
44 /* Use BSD man page specification. */
45 #define RANDOM_MAX (((long)(1)<<31)-1)
46 #define TWO_DIV_RANDOM_MAX (2. / ( ((long)(1)<<31)-1. ))
49 using namespace Shapes
;
56 class Core_nonNegativeModulo
: public Lang::CoreFunction
58 Lang::Float::ValueType
floatImpl( Lang::Float::ValueType num
, Lang::Float::ValueType den
) const
60 Lang::Float::ValueType absDen
= fabs( den
);
61 return num
- floor( num
/ absDen
) * absDen
;
64 Core_nonNegativeModulo( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
65 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
67 formals_
->appendEvaluatedCoreFormal( "dividend", Kernel::THE_SLOT_VARIABLE
);
68 formals_
->appendEvaluatedCoreFormal( "divisor", Kernel::THE_SLOT_VARIABLE
);
71 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
73 args
.applyDefaults( callLoc
);
77 typedef const Lang::Integer ArgType
;
78 Lang::Integer::ValueType num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) )->val_
;
79 Lang::Integer::ValueType den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
)->val_
;
81 /* Division num / abs(den) with rounding towards negative infinity.
83 Lang::Integer::ValueType absDen
= (den
>= 0) ? den
: (-den
);
84 Lang::Integer::ValueType n
= 0; /* Initialize to suppress warnings. */
89 n
= -( 1 + (-num
- 1) / absDen
);
91 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "The remainder is not defined when the denominator is zero." );
94 Kernel::ContRef cont
= evalState
->cont_
;
95 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( num
- n
* absDen
) ),
99 catch( const NonLocalExit::NotThisType
& ball
)
101 /* Wrong type; never mind!.. but see below!
107 typedef const Lang::Float ArgType
;
108 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
109 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
111 Kernel::ContRef cont
= evalState
->cont_
;
112 cont
->takeValue( Kernel::ValueRef( new Lang::Float( floatImpl( num
->val_
, den
->val_
) ) ),
116 catch( const NonLocalExit::NotThisType
& ball
)
118 /* Wrong type; never mind!.. but see below!
124 typedef const Lang::Length ArgType
;
125 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
126 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
128 Kernel::ContRef cont
= evalState
->cont_
;
129 cont
->takeValue( Kernel::ValueRef( new Lang::Length( floatImpl( num
->getScalar( ), den
->getScalar( ) ) ) ),
133 catch( const NonLocalExit::NotThisType
& ball
)
135 /* Wrong type; never mind!.. but see below!
139 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Integer::staticTypeName( ), Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
143 class Core_denominatorSignModulo
: public Lang::CoreFunction
145 Lang::Float::ValueType
floatImpl( Lang::Float::ValueType num
, Lang::Float::ValueType den
) const
147 return num
- floor( num
/ den
) * den
;
150 Core_denominatorSignModulo( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
151 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
153 formals_
->appendEvaluatedCoreFormal( "dividend", Kernel::THE_SLOT_VARIABLE
);
154 formals_
->appendEvaluatedCoreFormal( "divisor", Kernel::THE_SLOT_VARIABLE
);
157 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
159 args
.applyDefaults( callLoc
);
163 typedef const Lang::Integer ArgType
;
164 Lang::Integer::ValueType num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) )->val_
;
165 Lang::Integer::ValueType den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
)->val_
;
167 /* Division with rounding towards negative infinity.
169 Lang::Integer::ValueType n
= 0; /* Initialize to suppress warnings. */
174 n
= -( 1 + (-num
- 1) / den
);
175 } else if (den
< 0) {
177 n
= -( 1 + (num
- 1) / (-den
) );
181 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "The remainder is not defined when the denominator is zero." );
184 Kernel::ContRef cont
= evalState
->cont_
;
185 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( num
- n
* den
) ),
189 catch( const NonLocalExit::NotThisType
& ball
)
191 /* Wrong type; never mind!.. but see below!
197 typedef const Lang::Float ArgType
;
198 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
199 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
201 Kernel::ContRef cont
= evalState
->cont_
;
202 cont
->takeValue( Kernel::ValueRef( new Lang::Float( floatImpl( num
->val_
, den
->val_
) ) ),
206 catch( const NonLocalExit::NotThisType
& ball
)
208 /* Wrong type; never mind!.. but see below!
214 typedef const Lang::Length ArgType
;
215 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
216 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
218 Kernel::ContRef cont
= evalState
->cont_
;
219 cont
->takeValue( Kernel::ValueRef( new Lang::Length( floatImpl( num
->getScalar( ), den
->getScalar( ) ) ) ),
223 catch( const NonLocalExit::NotThisType
& ball
)
225 /* Wrong type; never mind!.. but see below!
229 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Integer::staticTypeName( ), Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
233 class Core_numeratorSignModulo
: public Lang::CoreFunction
235 Lang::Float::ValueType
floatImpl( Lang::Float::ValueType num
, Lang::Float::ValueType den
) const
237 return fmod( num
, den
);
240 Core_numeratorSignModulo( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
241 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
243 formals_
->appendEvaluatedCoreFormal( "dividend", Kernel::THE_SLOT_VARIABLE
);
244 formals_
->appendEvaluatedCoreFormal( "divisor", Kernel::THE_SLOT_VARIABLE
);
247 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
249 args
.applyDefaults( callLoc
);
253 typedef const Lang::Integer ArgType
;
254 Lang::Integer::ValueType num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) )->val_
;
255 Lang::Integer::ValueType den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
)->val_
;
257 /* Division with rounding towards zero.
259 Lang::Integer::ValueType n
= 0; /* Initialize to suppress warnings. */
264 n
= -( (-num
) / den
);
265 } else if (den
< 0) {
267 n
= -( num
/ (-den
) );
271 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "The remainder is not defined when the denominator is zero." );
274 Kernel::ContRef cont
= evalState
->cont_
;
275 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( num
- n
* den
) ),
279 catch( const NonLocalExit::NotThisType
& ball
)
281 /* Wrong type; never mind!.. but see below!
287 typedef const Lang::Float ArgType
;
288 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
289 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
291 Kernel::ContRef cont
= evalState
->cont_
;
292 cont
->takeValue( Kernel::ValueRef( new Lang::Float( floatImpl( num
->val_
, den
->val_
) ) ),
296 catch( const NonLocalExit::NotThisType
& ball
)
298 /* Wrong type; never mind!.. but see below!
304 typedef const Lang::Length ArgType
;
305 RefCountPtr
< ArgType
> num
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) );
306 RefCountPtr
< ArgType
> den
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
);
308 Kernel::ContRef cont
= evalState
->cont_
;
309 cont
->takeValue( Kernel::ValueRef( new Lang::Length( floatImpl( num
->getScalar( ), den
->getScalar( ) ) ) ),
313 catch( const NonLocalExit::NotThisType
& ball
)
315 /* Wrong type; never mind!.. but see below!
319 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Integer::staticTypeName( ), Lang::Float::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
323 class Core_floor
: public Lang::CoreFunction
326 Core_floor( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
328 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
330 const size_t ARITY
= 1;
331 CHECK_ARITY( args
, ARITY
, id_
);
333 typedef const Lang::Float ArgType
;
334 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
336 /* Warning, unhandled overflow in the static_cast from floating point to integral type.
338 Kernel::ContRef cont
= evalState
->cont_
;
339 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( static_cast< Lang::Integer::ValueType
>( floor( arg
->val_
) ) ) ),
344 class Core_ceil
: public Lang::CoreFunction
347 Core_ceil( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
349 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
351 const size_t ARITY
= 1;
352 CHECK_ARITY( args
, ARITY
, id_
);
354 typedef const Lang::Float ArgType
;
355 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
357 /* Warning, unhandled overflow in the static_cast from floating point to integral type.
359 Kernel::ContRef cont
= evalState
->cont_
;
360 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( static_cast< Lang::Integer::ValueType
>( ceil( arg
->val_
) ) ) ),
365 class Core_round
: public Lang::CoreFunction
368 Core_round( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
370 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
372 const size_t ARITY
= 1;
373 CHECK_ARITY( args
, ARITY
, id_
);
375 typedef const Lang::Float ArgType
;
376 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
378 /* Warning, there are two sources of unhandled overflow here.
379 * 1) The range of a double is much greater than the range of a long (the result of lround).
380 * 2) lround produces a long, while Lang::Integer::ValueType is currently int.
382 Kernel::ContRef cont
= evalState
->cont_
;
383 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( lround( arg
->val_
) ) ),
388 class Core_cos
: public Lang::CoreFunction
391 Core_cos( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
393 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
395 const size_t ARITY
= 1;
396 CHECK_ARITY( args
, ARITY
, id_
);
398 typedef const Lang::Float ArgType
;
399 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
401 Kernel::ContRef cont
= evalState
->cont_
;
402 cont
->takeValue( Kernel::ValueRef( new Lang::Float( cos( arg
->val_
) ) ),
407 class Core_sin
: public Lang::CoreFunction
410 Core_sin( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
412 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
414 const size_t ARITY
= 1;
415 CHECK_ARITY( args
, ARITY
, id_
);
417 typedef const Lang::Float ArgType
;
418 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
420 Kernel::ContRef cont
= evalState
->cont_
;
421 cont
->takeValue( Kernel::ValueRef( new Lang::Float( sin( arg
->val_
) ) ),
426 class Core_tan
: public Lang::CoreFunction
429 Core_tan( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
431 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
433 const size_t ARITY
= 1;
434 CHECK_ARITY( args
, ARITY
, id_
);
436 typedef const Lang::Float ArgType
;
437 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
439 Kernel::ContRef cont
= evalState
->cont_
;
440 cont
->takeValue( Kernel::ValueRef( new Lang::Float( tan( arg
->val_
) ) ),
445 class Core_cot
: public Lang::CoreFunction
448 Core_cot( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
450 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
452 const size_t ARITY
= 1;
453 CHECK_ARITY( args
, ARITY
, id_
);
455 typedef const Lang::Float ArgType
;
456 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
458 Kernel::ContRef cont
= evalState
->cont_
;
459 cont
->takeValue( Kernel::ValueRef( new Lang::Float( 1 / tan( arg
->val_
) ) ),
464 class Core_arccos
: public Lang::CoreFunction
467 Core_arccos( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
469 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
471 const size_t ARITY
= 1;
472 CHECK_ARITY( args
, ARITY
, id_
);
474 typedef const Lang::Float ArgType
;
475 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
477 Kernel::ContRef cont
= evalState
->cont_
;
478 cont
->takeValue( Kernel::ValueRef( new Lang::Float( acos( arg
->val_
) ) ),
483 class Core_arcsin
: public Lang::CoreFunction
486 Core_arcsin( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
488 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
490 const size_t ARITY
= 1;
491 CHECK_ARITY( args
, ARITY
, id_
);
493 typedef const Lang::Float ArgType
;
494 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
496 Kernel::ContRef cont
= evalState
->cont_
;
497 cont
->takeValue( Kernel::ValueRef( new Lang::Float( asin( arg
->val_
) ) ),
502 class Core_arctan
: public Lang::CoreFunction
505 Core_arctan( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
507 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
509 const size_t ARITY
= 1;
510 CHECK_ARITY( args
, ARITY
, id_
);
512 typedef const Lang::Float ArgType
;
513 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
515 Kernel::ContRef cont
= evalState
->cont_
;
516 cont
->takeValue( Kernel::ValueRef( new Lang::Float( atan( arg
->val_
) ) ),
521 class Core_pow
: public Lang::CoreFunction
524 Core_pow( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
526 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
528 const size_t ARITY
= 2;
529 CHECK_ARITY( args
, ARITY
, id_
);
533 typedef const Lang::Float ArgTypeBase
;
534 RefCountPtr
< ArgTypeBase
> b
= Helpers::try_cast_CoreArgument
< ArgTypeBase
>( args
.getValue( 0 ) );
538 typedef const Lang::Float ArgTypeExp
;
539 RefCountPtr
< ArgTypeExp
> e
= Helpers::try_cast_CoreArgument
< ArgTypeExp
>( args
.getValue( 1 ) );
541 Kernel::ContRef cont
= evalState
->cont_
;
542 cont
->takeValue( Kernel::ValueRef( new Lang::Float( pow( b
->val_
, e
->val_
) ) ),
546 catch( const NonLocalExit::NotThisType
& ball
)
548 /* Wrong type; never mind!.. but see below!
554 typedef const Lang::Integer ArgTypeExp
;
555 RefCountPtr
< ArgTypeExp
> e
= Helpers::try_cast_CoreArgument
< ArgTypeExp
>( args
.getValue( 1 ) );
557 Kernel::ContRef cont
= evalState
->cont_
;
558 cont
->takeValue( Kernel::ValueRef( new Lang::Float( pow( b
->val_
, e
->val_
) ) ),
562 catch( const NonLocalExit::NotThisType
& ball
)
564 /* Wrong type; never mind!.. but see below!
568 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 1, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Integer::staticTypeName( ) ) );
571 catch( const NonLocalExit::NotThisType
& ball
)
573 /* Wrong type; never mind!.. but see below!
579 typedef const Lang::Integer ArgType
;
580 ArgType::ValueType b
= Helpers::try_cast_CoreArgument
< ArgType
>( args
.getValue( 0 ) )->val_
;
581 ArgType::ValueType e
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 1, callLoc
)->val_
;
585 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "Power with integer base must have non-negative exponent." );
588 ArgType::ValueType result
= 1;
590 if( ( e
% 2 ) != 0 ){
597 Kernel::ContRef cont
= evalState
->cont_
;
598 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( result
) ),
602 catch( const NonLocalExit::NotThisType
& ball
)
604 /* Wrong type; never mind!.. but see below!
608 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Integer::staticTypeName( ) ) );
612 class Core_exp
: public Lang::CoreFunction
615 Core_exp( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
617 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
619 const size_t ARITY
= 1;
620 CHECK_ARITY( args
, ARITY
, id_
);
622 typedef const Lang::Float ArgType
;
623 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
625 Kernel::ContRef cont
= evalState
->cont_
;
626 cont
->takeValue( Kernel::ValueRef( new Lang::Float( exp( arg
->val_
) ) ),
631 class Core_log
: public Lang::CoreFunction
634 Core_log( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
636 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
638 const size_t ARITY
= 1;
639 CHECK_ARITY( args
, ARITY
, id_
);
641 typedef const Lang::Float ArgType
;
642 ArgType::ValueType arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
)->val_
;
645 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Argument must be strictly positive." );
648 Kernel::ContRef cont
= evalState
->cont_
;
649 cont
->takeValue( Kernel::ValueRef( new Lang::Float( log( arg
) ) ),
654 class Core_log10
: public Lang::CoreFunction
657 Core_log10( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
659 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
661 const size_t ARITY
= 1;
662 CHECK_ARITY( args
, ARITY
, id_
);
664 typedef const Lang::Float ArgType
;
665 ArgType::ValueType arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
)->val_
;
668 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Argument must be strictly positive." );
671 Kernel::ContRef cont
= evalState
->cont_
;
672 cont
->takeValue( Kernel::ValueRef( new Lang::Float( log10( arg
) ) ),
677 class Core_min
: public Lang::CoreFunction
680 Core_min( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
682 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
686 Kernel::ContRef cont
= evalState
->cont_
;
687 cont
->takeValue( Kernel::ValueRef( new Lang::Float( HUGE_VAL
) ),
693 typedef const Lang::Float ArgType
;
695 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
698 double res
= arg
->val_
;
700 const size_t & end
= args
.size( );
701 for( ; i
!= end
; ++i
)
703 res
= std::min( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->val_
);
705 Kernel::ContRef cont
= evalState
->cont_
;
706 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
713 typedef const Lang::Length ArgType
;
715 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
718 Concrete::Length res
= arg
->get( );
720 const size_t & end
= args
.size( );
721 for( ; i
!= end
; ++i
)
723 res
= std::min( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->get( ) );
725 Kernel::ContRef cont
= evalState
->cont_
;
726 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
733 typedef const Lang::Integer ArgType
;
735 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
738 Lang::Integer::ValueType res
= arg
->val_
;
740 const size_t & end
= args
.size( );
741 for( ; i
!= end
; ++i
)
743 res
= std::min( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->val_
);
745 Kernel::ContRef cont
= evalState
->cont_
;
746 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
752 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Integer::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
756 class Core_max
: public Lang::CoreFunction
759 Core_max( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
761 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
765 Kernel::ContRef cont
= evalState
->cont_
;
766 cont
->takeValue( Kernel::ValueRef( new Lang::Float( -HUGE_VAL
) ),
772 typedef const Lang::Float ArgType
;
774 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
777 double res
= arg
->val_
;
779 const size_t & end
= args
.size( );
780 for( ; i
!= end
; ++i
)
782 res
= std::max( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->val_
);
784 Kernel::ContRef cont
= evalState
->cont_
;
785 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
792 typedef const Lang::Length ArgType
;
794 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
797 Concrete::Length res
= arg
->get( );
799 const size_t & end
= args
.size( );
800 for( ; i
!= end
; ++i
)
802 res
= std::max( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->get( ) );
804 Kernel::ContRef cont
= evalState
->cont_
;
805 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
813 typedef const Lang::Integer ArgType
;
815 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( i
).getPtr( ) );
818 Lang::Integer::ValueType res
= arg
->val_
;
820 const size_t & end
= args
.size( );
821 for( ; i
!= end
; ++i
)
823 res
= std::max( res
, Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, i
, callLoc
)->val_
);
825 Kernel::ContRef cont
= evalState
->cont_
;
827 cont
->takeValue( Kernel::ValueRef( new ArgType( res
) ),
833 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::Float::staticTypeName( ), Lang::Integer::staticTypeName( ), Lang::Length::staticTypeName( ) ) );
837 class Core_sqrt
: public Lang::CoreFunction
840 Core_sqrt( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
842 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
844 const size_t ARITY
= 1;
845 CHECK_ARITY( args
, ARITY
, id_
);
847 typedef const Lang::Float ArgType
;
848 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
850 if( arg
->val_
< 0.0 )
852 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "The square root is not defined for negative values." );
855 Kernel::ContRef cont
= evalState
->cont_
;
856 cont
->takeValue( Kernel::ValueRef( new Lang::Float( sqrt( arg
->val_
) ) ),
861 class Core_angle
: public Lang::CoreFunction
864 Core_angle( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
866 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
868 const size_t ARITY
= 1;
869 CHECK_ARITY( args
, ARITY
, id_
);
872 typedef const Lang::Coords2D ArgType
;
873 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
876 if( arg
->x_
.get( ) == 0 && arg
->y_
.get( ) == 0 )
878 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't take the angle of something of norm 0." );
880 Kernel::ContRef cont
= evalState
->cont_
;
881 cont
->takeValue( Kernel::ValueRef( new Lang::Float( atan2( arg
->y_
.getScalar( ), arg
->x_
.getScalar( ) ) ) ),
888 typedef const Lang::FloatPair ArgType
;
889 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
892 if( arg
->x_
== 0 && arg
->y_
== 0 )
894 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't take the angle of something of norm 0." );
896 Kernel::ContRef cont
= evalState
->cont_
;
897 cont
->takeValue( Kernel::ValueRef( new Lang::Float( atan2( arg
->y_
, arg
->x_
) ) ),
903 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Interaction::SEVERAL_TYPES
);
907 class Core_dir
: public Lang::CoreFunction
910 Core_dir( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
912 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
914 const size_t ARITY
= 1;
915 CHECK_ARITY( args
, ARITY
, id_
);
917 typedef const Lang::Float ArgType
;
918 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
920 Kernel::ContRef cont
= evalState
->cont_
;
921 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( cos( arg
->val_
), sin( arg
->val_
) ) ),
926 class Core_abs
: public Lang::CoreFunction
929 Core_abs( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
931 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
933 const size_t ARITY
= 1;
934 CHECK_ARITY( args
, ARITY
, id_
);
936 const Lang::Value
* untypedArg
= args
.getValue( 0 ).getPtr( );
939 typedef const Lang::Float ArgType
;
940 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
943 Kernel::ContRef cont
= evalState
->cont_
;
944 cont
->takeValue( Kernel::ValueRef( new Lang::Float( fabs( arg
->val_
) ) ),
951 typedef const Lang::Length ArgType
;
952 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
955 Kernel::ContRef cont
= evalState
->cont_
;
956 cont
->takeValue( Kernel::ValueRef( new Lang::Length( arg
->get( ).abs( ) ) ),
963 typedef const Lang::FloatPair ArgType
;
964 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
967 Kernel::ContRef cont
= evalState
->cont_
;
968 cont
->takeValue( Kernel::ValueRef( new Lang::Float( hypot( arg
->x_
, arg
->y_
) ) ),
975 typedef const Lang::Coords2D ArgType
;
976 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
979 Kernel::ContRef cont
= evalState
->cont_
;
980 cont
->takeValue( Kernel::ValueRef( new Lang::Length( hypotPhysical( arg
->x_
.get( ), arg
->y_
.get( ) ) ) ),
987 typedef const Lang::FloatTriple ArgType
;
988 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
991 Kernel::ContRef cont
= evalState
->cont_
;
992 cont
->takeValue( Kernel::ValueRef( new Lang::Float( Concrete::Scalar::hypot3( arg
->x_
, arg
->y_
, arg
->z_
) ) ),
999 typedef const Lang::Coords3D ArgType
;
1000 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
1003 Kernel::ContRef cont
= evalState
->cont_
;
1004 cont
->takeValue( Kernel::ValueRef( new Lang::Length( hypotPhysical( arg
->x_
.get( ), arg
->y_
.get( ), arg
->z_
.get( ) ) ) ),
1011 typedef const Lang::ElementaryPath2D ArgType
;
1014 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry2D( args
.getValue( 0 ) );
1015 Kernel::ContRef cont
= evalState
->cont_
;
1016 cont
->takeValue( RefCountPtr
< const Lang::Length
>( new Lang::Length( p
->arcLength( ) ) ),
1020 catch( NonLocalExit::NotThisType
& ball
)
1027 typedef const Lang::ElementaryPath3D ArgType
;
1030 RefCountPtr
< ArgType
> p
= Helpers::elementaryPathTry3D( args
.getValue( 0 ) );
1031 Kernel::ContRef cont
= evalState
->cont_
;
1032 cont
->takeValue( RefCountPtr
< const Lang::Length
>( new Lang::Length( p
->arcLength( ) ) ),
1036 catch( NonLocalExit::NotThisType
& ball
)
1043 typedef const Lang::Integer ArgType
;
1044 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
1047 Kernel::ContRef cont
= evalState
->cont_
;
1048 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( ( arg
->val_
>= 0 ) ? (arg
->val_
) : (-arg
->val_
) ) ),
1055 typedef const Lang::Dash ArgType
;
1056 ArgType
* arg
= dynamic_cast< ArgType
* >( untypedArg
);
1059 Kernel::ContRef cont
= evalState
->cont_
;
1060 cont
->takeValue( Kernel::ValueRef( new Lang::Length( arg
->length( ) ) ),
1066 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Interaction::SEVERAL_TYPES
);
1070 class Core_normalized
: public Lang::CoreFunction
1073 Core_normalized( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
1075 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1077 const size_t ARITY
= 1;
1078 CHECK_ARITY( args
, ARITY
, id_
);
1081 typedef const Lang::FloatPair ArgType
;
1082 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1085 double norm
= hypot( arg
->x_
, arg
->y_
);
1088 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1090 Kernel::ContRef cont
= evalState
->cont_
;
1091 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( arg
->x_
/ norm
, arg
->y_
/ norm
) ),
1098 typedef const Lang::Coords2D ArgType
;
1099 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1102 Concrete::Length norm
= hypotPhysical( arg
->x_
.get( ), arg
->y_
.get( ) );
1105 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1107 Kernel::ContRef cont
= evalState
->cont_
;
1108 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( arg
->x_
.get( ) / norm
, arg
->y_
.get( ) / norm
) ),
1115 typedef const Lang::FloatTriple ArgType
;
1116 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1119 double norm
= Concrete::Scalar::hypot3( arg
->x_
, arg
->y_
, arg
->z_
);
1122 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1124 Kernel::ContRef cont
= evalState
->cont_
;
1125 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( arg
->x_
/ norm
, arg
->y_
/ norm
, arg
->z_
/ norm
) ),
1132 typedef const Lang::Coords3D ArgType
;
1133 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1136 Concrete::Length norm
= hypotPhysical( arg
->x_
.get( ), arg
->y_
.get( ), arg
->z_
.get( ) );
1139 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1141 Kernel::ContRef cont
= evalState
->cont_
;
1142 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( arg
->x_
.get( ) / norm
, arg
->y_
.get( ) / norm
, arg
->z_
.get( ) / norm
) ),
1149 typedef const Lang::Float ArgType
;
1150 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1155 Kernel::ContRef cont
= evalState
->cont_
;
1156 cont
->takeValue( Kernel::ValueRef( new Lang::Float( 1 ) ),
1162 Kernel::ContRef cont
= evalState
->cont_
;
1163 cont
->takeValue( Kernel::ValueRef( new Lang::Float( -1 ) ),
1167 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1172 typedef const Lang::Length ArgType
;
1173 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1176 if( arg
->get( ) > 0 )
1178 Kernel::ContRef cont
= evalState
->cont_
;
1179 cont
->takeValue( Kernel::ValueRef( new Lang::Float( 1 ) ),
1183 if( arg
->get( ) < 0 )
1185 Kernel::ContRef cont
= evalState
->cont_
;
1186 cont
->takeValue( Kernel::ValueRef( new Lang::Float( -1 ) ),
1190 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1195 typedef const Lang::Integer ArgType
;
1196 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1201 Kernel::ContRef cont
= evalState
->cont_
;
1202 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( 1 ) ),
1208 Kernel::ContRef cont
= evalState
->cont_
;
1209 cont
->takeValue( Kernel::ValueRef( new Lang::Integer( -1 ) ),
1213 throw Exceptions::CoreOutOfRange( id_
, args
, 0, "Can't normalize something of norm 0" );
1218 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Interaction::SEVERAL_TYPES
);
1222 class Core_cross
: public Lang::CoreFunction
1225 Core_cross( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
1227 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1229 const size_t ARITY
= 2;
1230 CHECK_ARITY( args
, ARITY
, id_
);
1238 bool isLength
= false;
1241 typedef const Lang::FloatTriple ArgType
;
1242 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1248 goto secondArgument
;
1253 typedef const Lang::Coords3D ArgType
;
1254 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 0 ).getPtr( ) );
1258 x1
= arg
->x_
.get( ).offtype
< 1, 0 >( );
1259 y1
= arg
->y_
.get( ).offtype
< 1, 0 >( );
1260 z1
= arg
->z_
.get( ).offtype
< 1, 0 >( );
1261 goto secondArgument
;
1265 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 0, Helpers::typeSetString( Lang::FloatTriple::staticTypeName( ), Lang::Coords3D::staticTypeName( ) ) );
1269 typedef const Lang::FloatTriple ArgType
;
1270 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 1 ).getPtr( ) );
1276 goto multiplyArguments
;
1281 typedef const Lang::Coords3D ArgType
;
1282 ArgType
* arg
= dynamic_cast< ArgType
* >( args
.getValue( 1 ).getPtr( ) );
1287 throw Exceptions::CoreOutOfRange( id_
, args
, 1, "Can't multiply two coordinate vectors. Try normalizing one of them!" );
1290 x2
= arg
->x_
.get( ).offtype
< 1, 0 >( );
1291 y2
= arg
->y_
.get( ).offtype
< 1, 0 >( );
1292 z2
= arg
->z_
.get( ).offtype
< 1, 0 >( );
1293 goto multiplyArguments
;
1297 throw Exceptions::CoreTypeMismatch( callLoc
, id_
, args
, 1, Helpers::typeSetString( Lang::FloatTriple::staticTypeName( ), Lang::Coords3D::staticTypeName( ) ) );
1300 Kernel::ContRef cont
= evalState
->cont_
;
1303 cont
->takeValue( Kernel::ValueRef( new Lang::Coords3D( Concrete::Length( y1
*z2
-z1
*y2
), Concrete::Length( z1
*x2
-x1
*z2
), Concrete::Length( x1
*y2
-y1
*x2
) ) ),
1308 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( y1
*z2
-z1
*y2
, z1
*x2
-x1
*z2
, x1
*y2
-y1
*x2
) ),
1314 class Core_orthogonal
: public Lang::CoreFunction
1317 Core_orthogonal( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
1319 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1321 const size_t ARITY
= 1;
1322 CHECK_ARITY( args
, ARITY
, id_
);
1324 typedef const Lang::FloatPair ArgType
;
1325 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
1327 Kernel::ContRef cont
= evalState
->cont_
;
1328 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( -arg
->y_
, arg
->x_
) ),
1333 class Core_orthogonal3D
: public Lang::CoreFunction
1336 Core_orthogonal3D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
) : CoreFunction( ns
, name
) { }
1338 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1340 const size_t ARITY
= 1;
1341 CHECK_ARITY( args
, ARITY
, id_
);
1343 typedef const Lang::FloatTriple ArgType
;
1344 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_CoreArgument
< ArgType
>( id_
, args
, 0, callLoc
);
1349 if( fabs( arg
->x_
) < fabs( arg
->y_
) )
1351 // arg is more parallell to y; cross with x
1358 // arg is more parallell to x; cross with y
1363 double scale
= sqrt( ( (arg
->x_
)*(arg
->x_
) + (arg
->y_
)*(arg
->y_
) + (arg
->z_
)*(arg
->z_
) ) / ( x
*x
+ y
*y
+ z
*z
) );
1364 Kernel::ContRef cont
= evalState
->cont_
;
1365 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( x
* scale
, y
* scale
, z
* scale
) ),
1370 class Core_randomBall1D
: public Lang::CoreFunction
1373 Core_randomBall1D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
1374 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1376 formals_
->appendCoreStateFormal( "state" );
1379 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1381 args
.applyDefaults( callLoc
);
1383 typedef Kernel::WarmRandomState StateType
;
1384 StateType
* st
= Helpers::down_cast_CoreState
< StateType
>( id_
, args
, 0, callLoc
);
1388 Kernel::ContRef cont
= evalState
->cont_
;
1389 cont
->takeValue( Kernel::ValueRef( new Lang::Float( TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1 ) ),
1394 class Core_randomBall2D
: public Lang::CoreFunction
1397 Core_randomBall2D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
1398 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1400 formals_
->appendCoreStateFormal( "state" );
1403 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1405 args
.applyDefaults( callLoc
);
1407 typedef Kernel::WarmRandomState StateType
;
1408 StateType
* st
= Helpers::down_cast_CoreState
< StateType
>( id_
, args
, 0, callLoc
);
1412 double x1
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1413 double x2
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1414 while( x1
* x1
+ x2
* x2
> 1 )
1416 x1
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1417 x2
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1420 Kernel::ContRef cont
= evalState
->cont_
;
1421 cont
->takeValue( Kernel::ValueRef( new Lang::FloatPair( x1
, x2
) ),
1426 class Core_randomBall3D
: public Lang::CoreFunction
1429 Core_randomBall3D( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
1430 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1432 formals_
->appendCoreStateFormal( "state" );
1435 call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1437 args
.applyDefaults( callLoc
);
1439 typedef Kernel::WarmRandomState StateType
;
1440 StateType
* st
= Helpers::down_cast_CoreState
< StateType
>( id_
, args
, 0, callLoc
);
1444 double x1
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1445 double x2
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1446 double x3
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1447 while( x1
* x1
+ x2
* x2
+ x3
* x3
> 1 )
1449 x1
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1450 x2
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1451 x3
= TWO_DIV_RANDOM_MAX
* static_cast< double >( random( ) ) - 1;
1454 Kernel::ContRef cont
= evalState
->cont_
;
1455 cont
->takeValue( Kernel::ValueRef( new Lang::FloatTriple( x1
, x2
, x3
) ),
1460 class Core_gensym
: public Lang::CoreFunction
1463 Core_gensym( const RefCountPtr
< const Ast::NamespacePath
> & ns
, const char * name
)
1464 : CoreFunction( ns
, name
, new Kernel::EvaluatedFormals( Ast::FileID::build_internal( name
), true ) )
1466 formals_
->appendCoreStateFormal( "state" );
1468 virtual void call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
1470 args
.applyDefaults( callLoc
);
1472 typedef Kernel::WarmTime StateType
;
1473 Helpers::down_cast_CoreState
< StateType
>( id_
, args
, 0, callLoc
); /* Ignore result, just make sure that a time state was given. */
1475 Kernel::ContRef cont
= evalState
->cont_
;
1476 cont
->takeValue( Kernel::ValueRef( new Lang::Symbol( ) ),
1484 RefCountPtr
< const Lang::CoreFunction
> Lang::THE_FUNCTION_ABS( new Lang::Core_abs( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "abs" ) );
1487 Kernel::registerCore_elem( Kernel::Environment
* env
)
1489 env
->initDefineCoreFunction( new Lang::Core_nonNegativeModulo( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "modulo" ) );
1490 env
->initDefineCoreFunction( new Lang::Core_denominatorSignModulo( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "mod" ) );
1491 env
->initDefineCoreFunction( new Lang::Core_numeratorSignModulo( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "rem" ) );
1492 env
->initDefineCoreFunction( new Lang::Core_ceil( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "ceil" ) );
1493 env
->initDefineCoreFunction( new Lang::Core_floor( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "floor" ) );
1494 env
->initDefineCoreFunction( new Lang::Core_round( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "round" ) );
1495 env
->initDefineCoreFunction( new Lang::Core_cos( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "cos" ) );
1496 env
->initDefineCoreFunction( new Lang::Core_sin( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "sin" ) );
1497 env
->initDefineCoreFunction( new Lang::Core_tan( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "tan" ) );
1498 env
->initDefineCoreFunction( new Lang::Core_cot( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "cot" ) );
1499 env
->initDefineCoreFunction( new Lang::Core_arccos( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "arccos" ) );
1500 env
->initDefineCoreFunction( new Lang::Core_arcsin( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "arcsin" ) );
1501 env
->initDefineCoreFunction( new Lang::Core_arctan( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "arctan" ) );
1502 env
->initDefineCoreFunction( new Lang::Core_pow( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "pow" ) );
1503 env
->initDefineCoreFunction( new Lang::Core_exp( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "exp" ) );
1504 env
->initDefineCoreFunction( new Lang::Core_log( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "log" ) );
1505 env
->initDefineCoreFunction( new Lang::Core_log10( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "log10" ) );
1506 env
->initDefineCoreFunction( new Lang::Core_min( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "min" ) );
1507 env
->initDefineCoreFunction( new Lang::Core_max( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "max" ) );
1508 env
->initDefineCoreFunction( new Lang::Core_sqrt( Lang::THE_NAMESPACE_Shapes_Numeric_Math
, "sqrt" ) );
1509 env
->initDefineCoreFunction( Lang::THE_FUNCTION_ABS
);
1510 env
->initDefineCoreFunction( new Lang::Core_angle( Lang::THE_NAMESPACE_Shapes_Geometry
, "angle" ) );
1511 env
->initDefineCoreFunction( new Lang::Core_dir( Lang::THE_NAMESPACE_Shapes_Geometry
, "dir" ) );
1512 env
->initDefineCoreFunction( new Lang::Core_normalized( Lang::THE_NAMESPACE_Shapes_Geometry
, "normalized" ) );
1513 env
->initDefineCoreFunction( new Lang::Core_cross( Lang::THE_NAMESPACE_Shapes_Geometry3D
, "cross" ) );
1514 env
->initDefineCoreFunction( new Lang::Core_orthogonal( Lang::THE_NAMESPACE_Shapes_Geometry
, "orthogonal" ) );
1515 env
->initDefineCoreFunction( new Lang::Core_orthogonal3D( Lang::THE_NAMESPACE_Shapes_Geometry3D
, "orthogonal" ) );
1517 env
->initDefineCoreFunction( new Lang::Core_randomBall1D( Lang::THE_NAMESPACE_Shapes_Numeric_Random
, "ball1D" ) );
1518 env
->initDefineCoreFunction( new Lang::Core_randomBall2D( Lang::THE_NAMESPACE_Shapes_Numeric_Random
, "ball2D" ) );
1519 env
->initDefineCoreFunction( new Lang::Core_randomBall3D( Lang::THE_NAMESPACE_Shapes_Numeric_Random
, "ball3D" ) );
1521 env
->initDefineCoreFunction( new Lang::Core_gensym( Lang::THE_NAMESPACE_Shapes
, "gensym" ) );