Updating the changelog in the VERSION file, and version_sync.
[shapes.git] / source / continuations.cc
blobbe622ed70f30bcc4744863692ee92a3e01469c78
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
6 * any later version.
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"
22 #include "hottypes.h"
23 #include "globals.h"
24 #include "shapescore.h"
25 #include "functiontypes.h"
26 #include "astfun.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 )
33 { }
35 Kernel::IfContinuation::~IfContinuation( )
36 { }
38 void
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 );
44 if( arg->val_ )
46 evalState->cont_ = cont_;
47 cont_->takeHandle( consequence_,
48 evalState );
50 else
52 evalState->cont_ = cont_;
53 cont_->takeHandle( alternative_,
54 evalState );
58 Kernel::ContRef
59 Kernel::IfContinuation::up( ) const
61 return cont_;
64 RefCountPtr< const char >
65 Kernel::IfContinuation::description( ) const
67 return strrefdup( "if" );
70 void
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 )
81 { }
83 Kernel::DefineVariableContinuation::~DefineVariableContinuation( )
84 { }
86 void
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.
90 if( val->isThunk( ) )
92 val->force( val, evalState );
94 else
96 env_->define( *pos_, val );
97 evalState->cont_ = cont_;
98 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
102 Kernel::ContRef
103 Kernel::DefineVariableContinuation::up( ) const
105 return cont_;
108 RefCountPtr< const char >
109 Kernel::DefineVariableContinuation::description( ) const
111 return strrefdup( "introduce cold" );
114 void
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( )
129 void
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 );
138 Kernel::ContRef
139 Kernel::IntroduceStateContinuation::up( ) const
141 return cont_;
144 RefCountPtr< const char >
145 Kernel::IntroduceStateContinuation::description( ) const
147 return strrefdup( "introduce warm" );
150 void
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( )
165 void
166 Kernel::StoreValueContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
168 if( val->isThunk( ) )
170 val->force( val, evalState );
172 else
174 *res_ = val->getUntyped( );
175 evalState->cont_ = cont_;
176 cont_->takeHandle( val, evalState );
180 Kernel::ContRef
181 Kernel::StoreValueContinuation::up( ) const
183 return cont_;
186 RefCountPtr< const char >
187 Kernel::StoreValueContinuation::description( ) const
189 return strrefdup( "store and return" );
192 void
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( )
206 void
207 Kernel::StoreVariableContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
209 if( val->isThunk( ) )
211 val->force( val, evalState );
213 else
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 );
222 Kernel::ContRef
223 Kernel::StoreVariableContinuation::up( ) const
225 return cont_;
228 RefCountPtr< const char >
229 Kernel::StoreVariableContinuation::description( ) const
231 return strrefdup( "store and return" );
234 void
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( )
249 void
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_ );
257 Kernel::ContRef
258 Kernel::InsertionContinuation::up( ) const
260 return cont_;
263 RefCountPtr< const char >
264 Kernel::InsertionContinuation::description( ) const
266 return strrefdup( "insertion" );
269 void
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( )
284 void
285 Kernel::StmtStoreValueContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
287 *res_ = val;
288 evalState->cont_ = cont_;
289 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
292 Kernel::ContRef
293 Kernel::StmtStoreValueContinuation::up( ) const
295 return cont_;
298 RefCountPtr< const char >
299 Kernel::StmtStoreValueContinuation::description( ) const
301 return strrefdup( "statement store (value)" );
304 void
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( )
318 void
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 );
327 Kernel::ContRef
328 Kernel::StmtStoreVariableContinuation::up( ) const
330 return cont_;
333 RefCountPtr< const char >
334 Kernel::StmtStoreVariableContinuation::description( ) const
336 return strrefdup( "statement store (variable)" );
339 void
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( )
355 void
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 );
365 Kernel::ContRef
366 Kernel::ForcingContinuation::up( ) const
368 return cont_;
371 RefCountPtr< const char >
372 Kernel::ForcingContinuation::description( ) const
374 return strrefdup( "force evaluation" );
377 void
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( )
391 void
392 Kernel::ExitContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
394 *done_ = true;
397 Kernel::ContRef
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)" );
409 void
410 Kernel::ExitContinuation::gcMark( Kernel::GCMarkedSet & marked )
414 Kernel::DefaultErrorContinuation::DefaultErrorContinuation( const Ast::SourceLocation & traceLoc )
415 : Kernel::Continuation( traceLoc )
418 Kernel::DefaultErrorContinuation::~DefaultErrorContinuation( )
421 void
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 ) );
427 Kernel::ContRef
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" );
439 void
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( )
451 void
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 ),
460 evalState );
461 return;
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_ ),
475 evalState );
476 return;
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( ) ) );
487 Kernel::ContRef
488 Kernel::Transform2DCont::up( ) const
490 return cont_;
493 RefCountPtr< const char >
494 Kernel::Transform2DCont::description( ) const
496 return strrefdup( "2D transform application" );
499 void
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( )
513 void
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 ),
522 evalState );
523 return;
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_ ),
537 evalState );
538 return;
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( ) ) );
549 Kernel::ContRef
550 Kernel::Transform3DCont::up( ) const
552 return cont_;
555 RefCountPtr< const char >
556 Kernel::Transform3DCont::description( ) const
558 return strrefdup( "3D transform application" );
561 void
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( )
575 void
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( ) ) ),
582 evalState );
583 return;
586 Kernel::ContRef
587 Kernel::PathApplication2DCont::up( ) const
589 return cont_;
592 RefCountPtr< const char >
593 Kernel::PathApplication2DCont::description( ) const
595 return strrefdup( "2D path point selection" );
598 void
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( )
613 void
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( ) ) ),
620 evalState );
621 return;
624 Kernel::ContRef
625 Kernel::PathApplication3DCont::up( ) const
627 return cont_;
630 RefCountPtr< const char >
631 Kernel::PathApplication3DCont::description( ) const
633 return strrefdup( "3D path point selection" );
636 void
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( )
651 void
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_ );
659 Kernel::ContRef
660 Kernel::ComposedFunctionCall_cont::up( ) const
662 return cont_;
665 RefCountPtr< const char >
666 Kernel::ComposedFunctionCall_cont::description( ) const
668 return strrefdup( "composed function's second application" );
671 void
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 );