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 Henrik Tidefelt
19 #include "Shapes_Helpers_decls.h"
21 #include "continuations.h"
24 #include "shapescore.h"
25 #include "functiontypes.h"
28 using namespace Shapes
;
31 Kernel::IfContinuation::IfContinuation( const Kernel::VariableHandle
& consequence
, const Kernel::VariableHandle
& alternative
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
32 : Kernel::Continuation( traceLoc
), consequence_( consequence
), alternative_( alternative
), cont_( cont
)
35 Kernel::IfContinuation::~IfContinuation( )
39 Kernel::IfContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
41 typedef const Lang::Boolean ArgType
;
42 RefCountPtr
< ArgType
> arg
= Helpers::down_cast_ContinuationArgument
< ArgType
>( val
, this );
46 evalState
->cont_
= cont_
;
47 cont_
->takeHandle( consequence_
,
52 evalState
->cont_
= cont_
;
53 cont_
->takeHandle( alternative_
,
59 Kernel::IfContinuation::up( ) const
64 RefCountPtr
< const char >
65 Kernel::IfContinuation::description( ) const
67 return strrefdup( "if" );
71 Kernel::IfContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
73 consequence_
->gcMark( marked
);
74 alternative_
->gcMark( marked
);
75 cont_
->gcMark( marked
);
79 Kernel::DefineVariableContinuation::DefineVariableContinuation( const Kernel::PassedEnv
& env
, size_t * pos
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
80 : Kernel::Continuation( traceLoc
), env_( env
), pos_( pos
), cont_( cont
)
83 Kernel::DefineVariableContinuation::~DefineVariableContinuation( )
87 Kernel::DefineVariableContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
89 // This continuation is only used when the expression is explicitly forced.
92 val
->force( val
, evalState
);
96 env_
->define( *pos_
, val
);
97 evalState
->cont_
= cont_
;
98 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
103 Kernel::DefineVariableContinuation::up( ) const
108 RefCountPtr
< const char >
109 Kernel::DefineVariableContinuation::description( ) const
111 return strrefdup( "introduce cold" );
115 Kernel::DefineVariableContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
117 env_
->gcMark( marked
);
118 cont_
->gcMark( marked
);
122 Kernel::IntroduceStateContinuation::IntroduceStateContinuation( const Kernel::PassedEnv
& env
, size_t * pos
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
123 : Kernel::Continuation( traceLoc
), env_( env
), pos_( pos
), cont_( cont
)
126 Kernel::IntroduceStateContinuation::~IntroduceStateContinuation( )
130 Kernel::IntroduceStateContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
132 typedef const Lang::Hot ArgType
;
133 RefCountPtr
< ArgType
> hot( Helpers::down_cast_ContinuationArgument
< ArgType
>( val
, this ) );
134 env_
->introduceState( *pos_
, hot
->newState( ) );
135 evalState
->cont_
= cont_
;
136 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
140 Kernel::IntroduceStateContinuation::up( ) const
145 RefCountPtr
< const char >
146 Kernel::IntroduceStateContinuation::description( ) const
148 return strrefdup( "introduce warm" );
152 Kernel::IntroduceStateContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
154 env_
->gcMark( marked
);
155 cont_
->gcMark( marked
);
159 Kernel::StoreValueContinuation::StoreValueContinuation( Kernel::ValueRef
* res
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
160 : Kernel::Continuation( traceLoc
), res_( res
), cont_( cont
)
163 Kernel::StoreValueContinuation::~StoreValueContinuation( )
167 Kernel::StoreValueContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
169 if( val
->isThunk( ) )
171 val
->force( val
, evalState
);
175 *res_
= val
->getUntyped( );
176 evalState
->cont_
= cont_
;
177 cont_
->takeHandle( val
, evalState
);
182 Kernel::StoreValueContinuation::up( ) const
187 RefCountPtr
< const char >
188 Kernel::StoreValueContinuation::description( ) const
190 return strrefdup( "store and return" );
194 Kernel::StoreValueContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
196 cont_
->gcMark( marked
);
200 Kernel::StoreVariableContinuation::StoreVariableContinuation( const Kernel::VariableHandle
& dst
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
201 : Kernel::Continuation( traceLoc
), dst_( dst
), cont_( cont
)
204 Kernel::StoreVariableContinuation::~StoreVariableContinuation( )
208 Kernel::StoreVariableContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
210 if( val
->isThunk( ) )
212 val
->force( val
, evalState
);
216 /* This class is friends with Variable, hence setValue is accessible. */
217 dst_
->setValue( val
->getUntyped( ) );
218 evalState
->cont_
= cont_
;
219 cont_
->takeHandle( val
, evalState
);
224 Kernel::StoreVariableContinuation::up( ) const
229 RefCountPtr
< const char >
230 Kernel::StoreVariableContinuation::description( ) const
232 return strrefdup( "store and return" );
236 Kernel::StoreVariableContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
238 dst_
->gcMark( marked
);
239 cont_
->gcMark( marked
);
243 Kernel::InsertionContinuation::InsertionContinuation( const Kernel::StateHandle
& dst
, const Kernel::ContRef
& cont
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& traceLoc
)
244 : Kernel::Continuation( traceLoc
), dst_( dst
), dyn_( dyn
), cont_( cont
)
247 Kernel::InsertionContinuation::~InsertionContinuation( )
251 Kernel::InsertionContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
253 evalState
->cont_
= cont_
;
254 evalState
->dyn_
= dyn_
; /* This is how we pass dyn_ to dst_->tackOn . Additionally passing it as a separate argument is (used to be) very confusing. */
255 dst_
->tackOn( evalState
, val
, traceLoc_
);
259 Kernel::InsertionContinuation::up( ) const
264 RefCountPtr
< const char >
265 Kernel::InsertionContinuation::description( ) const
267 return strrefdup( "insertion" );
271 Kernel::InsertionContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
273 cont_
->gcMark( marked
);
274 dyn_
->gcMark( marked
);
278 Kernel::StmtStoreValueContinuation::StmtStoreValueContinuation( Kernel::ValueRef
* res
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
279 : Kernel::Continuation( traceLoc
), res_( res
), cont_( cont
)
282 Kernel::StmtStoreValueContinuation::~StmtStoreValueContinuation( )
286 Kernel::StmtStoreValueContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
289 evalState
->cont_
= cont_
;
290 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
294 Kernel::StmtStoreValueContinuation::up( ) const
299 RefCountPtr
< const char >
300 Kernel::StmtStoreValueContinuation::description( ) const
302 return strrefdup( "statement store (value)" );
306 Kernel::StmtStoreValueContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
308 cont_
->gcMark( marked
);
312 Kernel::StmtStoreVariableContinuation::StmtStoreVariableContinuation( const Kernel::VariableHandle
& dst
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
313 : Kernel::Continuation( traceLoc
), dst_( dst
), cont_( cont
)
316 Kernel::StmtStoreVariableContinuation::~StmtStoreVariableContinuation( )
320 Kernel::StmtStoreVariableContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
322 /* This class is friends with Variable, hence setValue is accessible. */
323 dst_
->setValue( val
);
324 evalState
->cont_
= cont_
;
325 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
329 Kernel::StmtStoreVariableContinuation::up( ) const
334 RefCountPtr
< const char >
335 Kernel::StmtStoreVariableContinuation::description( ) const
337 return strrefdup( "statement store (variable)" );
341 Kernel::StmtStoreVariableContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
343 dst_
->gcMark( marked
);
344 cont_
->gcMark( marked
);
349 Kernel::ForcingContinuation::ForcingContinuation( const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
350 : Kernel::Continuation( traceLoc
), cont_( cont
)
353 Kernel::ForcingContinuation::~ForcingContinuation( )
357 Kernel::ForcingContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
359 /* The reason for using this is simply that it only takes values. Then, the value
360 * is passed to whatever surrounding continuation.
362 evalState
->cont_
= cont_
;
363 cont_
->takeValue( val
, evalState
);
367 Kernel::ForcingContinuation::up( ) const
372 RefCountPtr
< const char >
373 Kernel::ForcingContinuation::description( ) const
375 return strrefdup( "force evaluation" );
379 Kernel::ForcingContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
381 cont_
->gcMark( marked
);
385 Kernel::ForcingSingleListContinuation::ForcingSingleListContinuation( const RefCountPtr
< const Lang::SingleList
> & cdr
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
386 : Kernel::Continuation( traceLoc
), cont_( cont
), cdr_( cdr
)
389 Kernel::ForcingSingleListContinuation::~ForcingSingleListContinuation( )
393 Kernel::ForcingSingleListContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
395 /* When takeValue is invoked, this means that it is time to continue forcing the cdr_. */
396 typedef const Lang::SingleListPair PairType
;
397 PairType
* p
= dynamic_cast< PairType
* >( cdr_
.getPtr( ) );
401 evalState
->cont_
= cont_
;
402 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
405 evalState
->cont_
= Kernel::ContRef( new Kernel::ForcingSingleListContinuation( p
->cdr_
, cont_
, traceLoc_
) );
406 Kernel::VariableHandle carCopy
= p
->car_
.unconst_cast
< Kernel::Variable
>( );
407 carCopy
->force( carCopy
, evalState
);
411 Kernel::ForcingSingleListContinuation::up( ) const
416 RefCountPtr
< const char >
417 Kernel::ForcingSingleListContinuation::description( ) const
419 return strrefdup( "force entire SingleList" );
423 Kernel::ForcingSingleListContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
425 cont_
->gcMark( marked
);
426 const_cast< Lang::SingleList
* >( cdr_
.getPtr( ) )->gcMark( marked
);
430 Kernel::ExitContinuation::ExitContinuation( bool * done
, const Ast::SourceLocation
& traceLoc
)
431 : Kernel::Continuation( traceLoc
), done_( done
)
434 Kernel::ExitContinuation::~ExitContinuation( )
438 Kernel::ExitContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
444 Kernel::ExitContinuation::up( ) const
446 return Kernel::ContRef( NullPtr
< Kernel::Continuation
>( ) );
449 RefCountPtr
< const char >
450 Kernel::ExitContinuation::description( ) const
452 return strrefdup( "exit (non-forcing)" );
456 Kernel::ExitContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
460 Kernel::DefaultErrorContinuation::DefaultErrorContinuation( const Ast::SourceLocation
& traceLoc
)
461 : Kernel::Continuation( traceLoc
)
464 Kernel::DefaultErrorContinuation::~DefaultErrorContinuation( )
468 Kernel::DefaultErrorContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
470 throw Exceptions::UncaughtError( Helpers::down_cast_ContinuationArgument
< const Lang::Exception
>( val
, this ) );
474 Kernel::DefaultErrorContinuation::up( ) const
476 return Kernel::ContRef( NullPtr
< Kernel::Continuation
>( ) );
479 RefCountPtr
< const char >
480 Kernel::DefaultErrorContinuation::description( ) const
482 return strrefdup( "default error continuation" );
486 Kernel::DefaultErrorContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
490 Kernel::Transform2DCont::Transform2DCont( Lang::Transform2D tf
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
491 : Kernel::Continuation( traceLoc
), tf_( tf
), cont_( cont
)
494 Kernel::Transform2DCont::~Transform2DCont( )
498 Kernel::Transform2DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
502 typedef const Lang::Geometric2D ArgType
;
503 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
504 evalState
->cont_
= cont_
;
505 cont_
->takeValue( arg
->transformed( tf_
, arg
),
509 catch( const NonLocalExit::NotThisType
& ball
)
511 /* Wrong type; never mind!.. but see below!
517 typedef const Lang::FloatPair ArgType
;
518 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
519 evalState
->cont_
= cont_
;
520 cont_
->takeValue( arg
->transformed( tf_
),
524 catch( const NonLocalExit::NotThisType
& ball
)
526 /* Wrong type; never mind!.. but see below!
530 throw Exceptions::ContinuationTypeMismatch( this, val
->getTypeName( ), Helpers::typeSetString( Lang::Geometric2D::staticTypeName( ), Lang::FloatPair::staticTypeName( ) ) );
534 Kernel::Transform2DCont::up( ) const
539 RefCountPtr
< const char >
540 Kernel::Transform2DCont::description( ) const
542 return strrefdup( "2D transform application" );
546 Kernel::Transform2DCont::gcMark( Kernel::GCMarkedSet
& marked
)
548 cont_
->gcMark( marked
);
552 Kernel::Transform3DCont::Transform3DCont( Lang::Transform3D tf
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
553 : Kernel::Continuation( traceLoc
), tf_( tf
), cont_( cont
)
556 Kernel::Transform3DCont::~Transform3DCont( )
560 Kernel::Transform3DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
564 typedef const Lang::Geometric3D ArgType
;
565 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
566 evalState
->cont_
= cont_
;
567 cont_
->takeValue( arg
->transformed( tf_
, arg
),
571 catch( const NonLocalExit::NotThisType
& ball
)
573 /* Wrong type; never mind!.. but see below!
579 typedef const Lang::FloatTriple ArgType
;
580 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
581 evalState
->cont_
= cont_
;
582 cont_
->takeValue( arg
->transformed( tf_
),
586 catch( const NonLocalExit::NotThisType
& ball
)
588 /* Wrong type; never mind!.. but see below!
592 throw Exceptions::ContinuationTypeMismatch( this, val
->getTypeName( ), Helpers::typeSetString( Lang::Geometric3D::staticTypeName( ), Lang::FloatTriple::staticTypeName( ) ) );
596 Kernel::Transform3DCont::up( ) const
601 RefCountPtr
< const char >
602 Kernel::Transform3DCont::description( ) const
604 return strrefdup( "3D transform application" );
608 Kernel::Transform3DCont::gcMark( Kernel::GCMarkedSet
& marked
)
610 cont_
->gcMark( marked
);
614 Kernel::PathApplication2DCont::PathApplication2DCont( RefCountPtr
< const Lang::ElementaryPath2D
> path
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
615 : Kernel::Continuation( traceLoc
), path_( path
), cont_( cont
)
618 Kernel::PathApplication2DCont::~PathApplication2DCont( )
622 Kernel::PathApplication2DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
624 Concrete::SplineTime t
= Helpers::pathTimeCast( path_
.getPtr( ), val
.getPtr( ), this );
626 evalState
->cont_
= cont_
;
627 cont_
->takeValue( Kernel::ValueRef( new Lang::PathSlider2D( path_
, t
.t( ) ) ),
633 Kernel::PathApplication2DCont::up( ) const
638 RefCountPtr
< const char >
639 Kernel::PathApplication2DCont::description( ) const
641 return strrefdup( "2D path point selection" );
645 Kernel::PathApplication2DCont::gcMark( Kernel::GCMarkedSet
& marked
)
647 const_cast< Lang::ElementaryPath2D
* >( path_
.getPtr( ) )->gcMark( marked
);
648 cont_
->gcMark( marked
);
652 Kernel::PathApplication3DCont::PathApplication3DCont( RefCountPtr
< const Lang::ElementaryPath3D
> path
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
653 : Kernel::Continuation( traceLoc
), path_( path
), cont_( cont
)
656 Kernel::PathApplication3DCont::~PathApplication3DCont( )
660 Kernel::PathApplication3DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
662 Concrete::SplineTime t
= Helpers::pathTimeCast( path_
.getPtr( ), val
.getPtr( ), this );
664 evalState
->cont_
= cont_
;
665 cont_
->takeValue( Kernel::ValueRef( new Lang::PathSlider3D( path_
, t
.t( ) ) ),
671 Kernel::PathApplication3DCont::up( ) const
676 RefCountPtr
< const char >
677 Kernel::PathApplication3DCont::description( ) const
679 return strrefdup( "3D path point selection" );
683 Kernel::PathApplication3DCont::gcMark( Kernel::GCMarkedSet
& marked
)
685 const_cast< Lang::ElementaryPath3D
* >( path_
.getPtr( ) )->gcMark( marked
);
686 cont_
->gcMark( marked
);
690 Kernel::ComposedFunctionCall_cont::ComposedFunctionCall_cont( const RefCountPtr
< const Lang::Function
> & second
, const Kernel::PassedDyn
& dyn
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& callLoc
)
691 : Kernel::Continuation( callLoc
), second_( second
), dyn_( dyn
), cont_( cont
)
694 Kernel::ComposedFunctionCall_cont::~ComposedFunctionCall_cont( )
698 Kernel::ComposedFunctionCall_cont::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
700 evalState
->dyn_
= dyn_
;
701 evalState
->cont_
= cont_
;
702 second_
->call( second_
, evalState
, val
, traceLoc_
);
706 Kernel::ComposedFunctionCall_cont::up( ) const
711 RefCountPtr
< const char >
712 Kernel::ComposedFunctionCall_cont::description( ) const
714 return strrefdup( "composed function's second application" );
718 Kernel::ComposedFunctionCall_cont::gcMark( Kernel::GCMarkedSet
& marked
)
720 const_cast< Lang::Function
* >( second_
.getPtr( ) )->gcMark( marked
);
721 dyn_
->gcMark( marked
);
722 cont_
->gcMark( marked
);
726 Kernel::ForceFunctionAndCall_2_args_cont::ForceFunctionAndCall_2_args_cont( const Kernel::VariableHandle
& arg1
, const Kernel::VariableHandle
& arg2
, const Kernel::PassedDyn
& dyn
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& callLoc
)
727 : Kernel::Continuation( callLoc
), arg1_( arg1
), arg2_( arg2
), dyn_( dyn
), cont_( cont
)
730 Kernel::ForceFunctionAndCall_2_args_cont::~ForceFunctionAndCall_2_args_cont( )
734 Kernel::ForceFunctionAndCall_2_args_cont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
736 evalState
->dyn_
= dyn_
;
737 evalState
->cont_
= cont_
;
738 typedef const Lang::Function ArgType
;
739 RefCountPtr
< ArgType
> fun( Helpers::down_cast_ContinuationArgument
< ArgType
>( val
, this ) );
740 fun
->call( fun
, evalState
, arg1_
, arg2_
, traceLoc_
);
744 Kernel::ForceFunctionAndCall_2_args_cont::up( ) const
749 RefCountPtr
< const char >
750 Kernel::ForceFunctionAndCall_2_args_cont::description( ) const
752 return strrefdup( "call function with two values" );
756 Kernel::ForceFunctionAndCall_2_args_cont::gcMark( Kernel::GCMarkedSet
& marked
)
758 arg1_
->gcMark( marked
);
759 arg2_
->gcMark( marked
);
760 dyn_
->gcMark( marked
);
761 cont_
->gcMark( marked
);