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 RefCountPtr
< const Lang::Hot
> hot( Helpers::down_cast
< const Lang::Hot
>( val
, traceLoc_
) );
133 env_
->introduceState( *pos_
, hot
->newState( ) );
134 evalState
->cont_
= cont_
;
135 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
139 Kernel::IntroduceStateContinuation::up( ) const
144 RefCountPtr
< const char >
145 Kernel::IntroduceStateContinuation::description( ) const
147 return strrefdup( "introduce warm" );
151 Kernel::IntroduceStateContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
153 env_
->gcMark( marked
);
154 cont_
->gcMark( marked
);
158 Kernel::StoreValueContinuation::StoreValueContinuation( Kernel::ValueRef
* res
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
159 : Kernel::Continuation( traceLoc
), res_( res
), cont_( cont
)
162 Kernel::StoreValueContinuation::~StoreValueContinuation( )
166 Kernel::StoreValueContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
168 if( val
->isThunk( ) )
170 val
->force( val
, evalState
);
174 *res_
= val
->getUntyped( );
175 evalState
->cont_
= cont_
;
176 cont_
->takeHandle( val
, evalState
);
181 Kernel::StoreValueContinuation::up( ) const
186 RefCountPtr
< const char >
187 Kernel::StoreValueContinuation::description( ) const
189 return strrefdup( "store and return" );
193 Kernel::StoreValueContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
195 cont_
->gcMark( marked
);
199 Kernel::StoreVariableContinuation::StoreVariableContinuation( const Kernel::VariableHandle
& dst
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
200 : Kernel::Continuation( traceLoc
), dst_( dst
), cont_( cont
)
203 Kernel::StoreVariableContinuation::~StoreVariableContinuation( )
207 Kernel::StoreVariableContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
209 if( val
->isThunk( ) )
211 val
->force( val
, evalState
);
215 /* This class is friends with Variable, hence setValue is accessible. */
216 dst_
->setValue( val
->getUntyped( ) );
217 evalState
->cont_
= cont_
;
218 cont_
->takeHandle( val
, evalState
);
223 Kernel::StoreVariableContinuation::up( ) const
228 RefCountPtr
< const char >
229 Kernel::StoreVariableContinuation::description( ) const
231 return strrefdup( "store and return" );
235 Kernel::StoreVariableContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
237 dst_
->gcMark( marked
);
238 cont_
->gcMark( marked
);
242 Kernel::InsertionContinuation::InsertionContinuation( const Kernel::StateHandle
& dst
, const Kernel::ContRef
& cont
, const Kernel::PassedDyn
& dyn
, const Ast::SourceLocation
& traceLoc
)
243 : Kernel::Continuation( traceLoc
), dst_( dst
), dyn_( dyn
), cont_( cont
)
246 Kernel::InsertionContinuation::~InsertionContinuation( )
250 Kernel::InsertionContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
252 evalState
->cont_
= cont_
;
253 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. */
254 dst_
->tackOn( evalState
, val
, traceLoc_
);
258 Kernel::InsertionContinuation::up( ) const
263 RefCountPtr
< const char >
264 Kernel::InsertionContinuation::description( ) const
266 return strrefdup( "insertion" );
270 Kernel::InsertionContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
272 cont_
->gcMark( marked
);
273 dyn_
->gcMark( marked
);
277 Kernel::StmtStoreValueContinuation::StmtStoreValueContinuation( Kernel::ValueRef
* res
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
278 : Kernel::Continuation( traceLoc
), res_( res
), cont_( cont
)
281 Kernel::StmtStoreValueContinuation::~StmtStoreValueContinuation( )
285 Kernel::StmtStoreValueContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
288 evalState
->cont_
= cont_
;
289 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
293 Kernel::StmtStoreValueContinuation::up( ) const
298 RefCountPtr
< const char >
299 Kernel::StmtStoreValueContinuation::description( ) const
301 return strrefdup( "statement store (value)" );
305 Kernel::StmtStoreValueContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
307 cont_
->gcMark( marked
);
311 Kernel::StmtStoreVariableContinuation::StmtStoreVariableContinuation( const Kernel::VariableHandle
& dst
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
312 : Kernel::Continuation( traceLoc
), dst_( dst
), cont_( cont
)
315 Kernel::StmtStoreVariableContinuation::~StmtStoreVariableContinuation( )
319 Kernel::StmtStoreVariableContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
321 /* This class is friends with Variable, hence setValue is accessible. */
322 dst_
->setValue( val
);
323 evalState
->cont_
= cont_
;
324 cont_
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
328 Kernel::StmtStoreVariableContinuation::up( ) const
333 RefCountPtr
< const char >
334 Kernel::StmtStoreVariableContinuation::description( ) const
336 return strrefdup( "statement store (variable)" );
340 Kernel::StmtStoreVariableContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
342 dst_
->gcMark( marked
);
343 cont_
->gcMark( marked
);
348 Kernel::ForcingContinuation::ForcingContinuation( const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
349 : Kernel::Continuation( traceLoc
), cont_( cont
)
352 Kernel::ForcingContinuation::~ForcingContinuation( )
356 Kernel::ForcingContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
358 /* The reason for using this is simply that it only takes values. Then, the value
359 * is passed to whatever surrounding continuation.
361 evalState
->cont_
= cont_
;
362 cont_
->takeValue( val
, evalState
);
366 Kernel::ForcingContinuation::up( ) const
371 RefCountPtr
< const char >
372 Kernel::ForcingContinuation::description( ) const
374 return strrefdup( "force evaluation" );
378 Kernel::ForcingContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
380 cont_
->gcMark( marked
);
384 Kernel::ExitContinuation::ExitContinuation( bool * done
, const Ast::SourceLocation
& traceLoc
)
385 : Kernel::Continuation( traceLoc
), done_( done
)
388 Kernel::ExitContinuation::~ExitContinuation( )
392 Kernel::ExitContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
398 Kernel::ExitContinuation::up( ) const
400 return Kernel::ContRef( NullPtr
< Kernel::Continuation
>( ) );
403 RefCountPtr
< const char >
404 Kernel::ExitContinuation::description( ) const
406 return strrefdup( "exit (non-forcing)" );
410 Kernel::ExitContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
414 Kernel::DefaultErrorContinuation::DefaultErrorContinuation( const Ast::SourceLocation
& traceLoc
)
415 : Kernel::Continuation( traceLoc
)
418 Kernel::DefaultErrorContinuation::~DefaultErrorContinuation( )
422 Kernel::DefaultErrorContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
424 throw Exceptions::UncaughtError( Helpers::down_cast_ContinuationArgument
< const Lang::Exception
>( val
, this ) );
428 Kernel::DefaultErrorContinuation::up( ) const
430 return Kernel::ContRef( NullPtr
< Kernel::Continuation
>( ) );
433 RefCountPtr
< const char >
434 Kernel::DefaultErrorContinuation::description( ) const
436 return strrefdup( "default error continuation" );
440 Kernel::DefaultErrorContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
444 Kernel::Transform2DCont::Transform2DCont( Lang::Transform2D tf
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
445 : Kernel::Continuation( traceLoc
), tf_( tf
), cont_( cont
)
448 Kernel::Transform2DCont::~Transform2DCont( )
452 Kernel::Transform2DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
456 typedef const Lang::Geometric2D ArgType
;
457 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
458 evalState
->cont_
= cont_
;
459 cont_
->takeValue( arg
->transformed( tf_
, arg
),
463 catch( const NonLocalExit::NotThisType
& ball
)
465 /* Wrong type; never mind!.. but see below!
471 typedef const Lang::FloatPair ArgType
;
472 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
473 evalState
->cont_
= cont_
;
474 cont_
->takeValue( arg
->transformed( tf_
),
478 catch( const NonLocalExit::NotThisType
& ball
)
480 /* Wrong type; never mind!.. but see below!
484 throw Exceptions::ContinuationTypeMismatch( this, val
->getTypeName( ), Helpers::typeSetString( Lang::Geometric2D::staticTypeName( ), Lang::FloatPair::staticTypeName( ) ) );
488 Kernel::Transform2DCont::up( ) const
493 RefCountPtr
< const char >
494 Kernel::Transform2DCont::description( ) const
496 return strrefdup( "2D transform application" );
500 Kernel::Transform2DCont::gcMark( Kernel::GCMarkedSet
& marked
)
502 cont_
->gcMark( marked
);
506 Kernel::Transform3DCont::Transform3DCont( Lang::Transform3D tf
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
507 : Kernel::Continuation( traceLoc
), tf_( tf
), cont_( cont
)
510 Kernel::Transform3DCont::~Transform3DCont( )
514 Kernel::Transform3DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
518 typedef const Lang::Geometric3D ArgType
;
519 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
520 evalState
->cont_
= cont_
;
521 cont_
->takeValue( arg
->transformed( tf_
, arg
),
525 catch( const NonLocalExit::NotThisType
& ball
)
527 /* Wrong type; never mind!.. but see below!
533 typedef const Lang::FloatTriple ArgType
;
534 RefCountPtr
< ArgType
> arg
= Helpers::try_cast_CoreArgument
< ArgType
>( val
);
535 evalState
->cont_
= cont_
;
536 cont_
->takeValue( arg
->transformed( tf_
),
540 catch( const NonLocalExit::NotThisType
& ball
)
542 /* Wrong type; never mind!.. but see below!
546 throw Exceptions::ContinuationTypeMismatch( this, val
->getTypeName( ), Helpers::typeSetString( Lang::Geometric3D::staticTypeName( ), Lang::FloatTriple::staticTypeName( ) ) );
550 Kernel::Transform3DCont::up( ) const
555 RefCountPtr
< const char >
556 Kernel::Transform3DCont::description( ) const
558 return strrefdup( "3D transform application" );
562 Kernel::Transform3DCont::gcMark( Kernel::GCMarkedSet
& marked
)
564 cont_
->gcMark( marked
);
568 Kernel::PathApplication2DCont::PathApplication2DCont( RefCountPtr
< const Lang::ElementaryPath2D
> path
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
569 : Kernel::Continuation( traceLoc
), path_( path
), cont_( cont
)
572 Kernel::PathApplication2DCont::~PathApplication2DCont( )
576 Kernel::PathApplication2DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
578 Concrete::SplineTime t
= Helpers::pathTimeCast( path_
.getPtr( ), val
.getPtr( ), this );
580 evalState
->cont_
= cont_
;
581 cont_
->takeValue( Kernel::ValueRef( new Lang::PathSlider2D( path_
, t
.t( ) ) ),
587 Kernel::PathApplication2DCont::up( ) const
592 RefCountPtr
< const char >
593 Kernel::PathApplication2DCont::description( ) const
595 return strrefdup( "2D path point selection" );
599 Kernel::PathApplication2DCont::gcMark( Kernel::GCMarkedSet
& marked
)
601 const_cast< Lang::ElementaryPath2D
* >( path_
.getPtr( ) )->gcMark( marked
);
602 cont_
->gcMark( marked
);
606 Kernel::PathApplication3DCont::PathApplication3DCont( RefCountPtr
< const Lang::ElementaryPath3D
> path
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
607 : Kernel::Continuation( traceLoc
), path_( path
), cont_( cont
)
610 Kernel::PathApplication3DCont::~PathApplication3DCont( )
614 Kernel::PathApplication3DCont::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
616 Concrete::SplineTime t
= Helpers::pathTimeCast( path_
.getPtr( ), val
.getPtr( ), this );
618 evalState
->cont_
= cont_
;
619 cont_
->takeValue( Kernel::ValueRef( new Lang::PathSlider3D( path_
, t
.t( ) ) ),
625 Kernel::PathApplication3DCont::up( ) const
630 RefCountPtr
< const char >
631 Kernel::PathApplication3DCont::description( ) const
633 return strrefdup( "3D path point selection" );
637 Kernel::PathApplication3DCont::gcMark( Kernel::GCMarkedSet
& marked
)
639 const_cast< Lang::ElementaryPath3D
* >( path_
.getPtr( ) )->gcMark( marked
);
640 cont_
->gcMark( marked
);
644 Kernel::ComposedFunctionCall_cont::ComposedFunctionCall_cont( const RefCountPtr
< const Lang::Function
> & second
, const Kernel::PassedDyn
& dyn
, const Kernel::ContRef
& cont
, const Ast::SourceLocation
& callLoc
)
645 : Kernel::Continuation( callLoc
), second_( second
), dyn_( dyn
), cont_( cont
)
648 Kernel::ComposedFunctionCall_cont::~ComposedFunctionCall_cont( )
652 Kernel::ComposedFunctionCall_cont::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
654 evalState
->dyn_
= dyn_
;
655 evalState
->cont_
= cont_
;
656 second_
->call( second_
, evalState
, val
, traceLoc_
);
660 Kernel::ComposedFunctionCall_cont::up( ) const
665 RefCountPtr
< const char >
666 Kernel::ComposedFunctionCall_cont::description( ) const
668 return strrefdup( "composed function's second application" );
672 Kernel::ComposedFunctionCall_cont::gcMark( Kernel::GCMarkedSet
& marked
)
674 const_cast< Lang::Function
* >( second_
.getPtr( ) )->gcMark( marked
);
675 dyn_
->gcMark( marked
);
676 cont_
->gcMark( marked
);