Update suitable examples and tests to use blank mode
[shapes.git] / source / continuations.cc
blob23bdab976a3751228bc80f9b6d21d3d18301a096
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, 2013, 2014 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"
27 #include "astvalues.h"
28 #include "singlelistrange.h"
30 using namespace Shapes;
33 Kernel::IfContinuation::IfContinuation( const Kernel::VariableHandle & consequence, const Kernel::VariableHandle & alternative, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
34 : Kernel::Continuation( traceLoc ), consequence_( consequence ), alternative_( alternative ), cont_( cont )
35 { }
37 Kernel::IfContinuation::~IfContinuation( )
38 { }
40 void
41 Kernel::IfContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
43 typedef const Lang::Boolean ArgType;
44 RefCountPtr< ArgType > arg = Helpers::down_cast_ContinuationArgument< ArgType >( val, this );
46 if( arg->val_ )
48 evalState->cont_ = cont_;
49 cont_->takeHandle( consequence_,
50 evalState );
52 else
54 evalState->cont_ = cont_;
55 cont_->takeHandle( alternative_,
56 evalState );
60 Kernel::ContRef
61 Kernel::IfContinuation::up( ) const
63 return cont_;
66 RefCountPtr< const char >
67 Kernel::IfContinuation::description( ) const
69 return strrefdup( "if" );
72 void
73 Kernel::IfContinuation::gcMark( Kernel::GCMarkedSet & marked )
75 consequence_->gcMark( marked );
76 alternative_->gcMark( marked );
77 cont_->gcMark( marked );
81 Kernel::IgnoreContinuation::IgnoreContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
82 : Kernel::Continuation( traceLoc ), cont_( cont )
83 { }
85 Kernel::IgnoreContinuation::~IgnoreContinuation( )
86 { }
88 void
89 Kernel::IgnoreContinuation::takeHandle( Kernel::VariableHandle, Kernel::EvalState * evalState, bool dummy ) const
91 evalState->cont_ = cont_;
92 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
95 Kernel::ContRef
96 Kernel::IgnoreContinuation::up( ) const
98 return cont_;
101 RefCountPtr< const char >
102 Kernel::IgnoreContinuation::description( ) const
104 return strrefdup( "ignore" );
107 void
108 Kernel::IgnoreContinuation::gcMark( Kernel::GCMarkedSet & marked )
110 cont_->gcMark( marked );
114 Kernel::IntroduceStateContinuation::IntroduceStateContinuation( const Kernel::PassedEnv & env, size_t * pos, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
115 : Kernel::Continuation( traceLoc ), env_( env ), pos_( pos ), cont_( cont )
118 Kernel::IntroduceStateContinuation::~IntroduceStateContinuation( )
121 void
122 Kernel::IntroduceStateContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
124 typedef const Lang::Hot ArgType;
125 RefCountPtr< ArgType > hot( Helpers::down_cast_ContinuationArgument< ArgType >( val, this ) );
126 env_->introduceState( *pos_, hot->newState( ) );
127 evalState->cont_ = cont_;
128 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
131 Kernel::ContRef
132 Kernel::IntroduceStateContinuation::up( ) const
134 return cont_;
137 RefCountPtr< const char >
138 Kernel::IntroduceStateContinuation::description( ) const
140 return strrefdup( "introduce state" );
143 void
144 Kernel::IntroduceStateContinuation::gcMark( Kernel::GCMarkedSet & marked )
146 env_->gcMark( marked );
147 cont_->gcMark( marked );
151 Kernel::StoreValueContinuation::StoreValueContinuation( Kernel::ValueRef * res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
152 : Kernel::Continuation( traceLoc ), res_( res ), cont_( cont )
155 Kernel::StoreValueContinuation::~StoreValueContinuation( )
158 void
159 Kernel::StoreValueContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
161 if( val->isThunk( ) )
163 val->force( val, evalState );
165 else
167 *res_ = val->getUntyped( );
168 evalState->cont_ = cont_;
169 cont_->takeHandle( val, evalState );
173 Kernel::ContRef
174 Kernel::StoreValueContinuation::up( ) const
176 return cont_;
179 RefCountPtr< const char >
180 Kernel::StoreValueContinuation::description( ) const
182 return strrefdup( "store and return" );
185 void
186 Kernel::StoreValueContinuation::gcMark( Kernel::GCMarkedSet & marked )
188 cont_->gcMark( marked );
192 Kernel::StoreVariableContinuation::StoreVariableContinuation( const Kernel::VariableHandle & dst, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
193 : Kernel::Continuation( traceLoc ), dst_( dst ), cont_( cont )
196 Kernel::StoreVariableContinuation::~StoreVariableContinuation( )
199 void
200 Kernel::StoreVariableContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
202 if( val->isThunk( ) )
204 val->force( val, evalState );
206 else
208 try{
209 /* This class is friends with Variable, hence setValue is accessible. */
210 dst_->setValue( val->getUntyped( ) );
211 }catch( const Exceptions::BadSetValueState & ball ){
212 throw Exceptions::InternalError( traceLoc_, "Multiple uses of continuation that stores value in variable." );
214 evalState->cont_ = cont_;
215 cont_->takeHandle( val, evalState );
219 Kernel::ContRef
220 Kernel::StoreVariableContinuation::up( ) const
222 return cont_;
225 RefCountPtr< const char >
226 Kernel::StoreVariableContinuation::description( ) const
228 return strrefdup( "store and return" );
231 void
232 Kernel::StoreVariableContinuation::gcMark( Kernel::GCMarkedSet & marked )
234 dst_->gcMark( marked );
235 cont_->gcMark( marked );
239 Kernel::InsertionContinuation::InsertionContinuation( const Kernel::StateHandle & dst, const Kernel::ContRef & cont, const Kernel::PassedDyn & dyn, const Ast::SourceLocation & traceLoc )
240 : Kernel::Continuation( traceLoc ), dst_( dst ), dyn_( dyn ), cont_( cont )
243 Kernel::InsertionContinuation::~InsertionContinuation( )
246 void
247 Kernel::InsertionContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
249 evalState->cont_ = cont_;
250 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. */
251 dst_->tackOn( evalState, val, traceLoc_ );
254 Kernel::ContRef
255 Kernel::InsertionContinuation::up( ) const
257 return cont_;
260 RefCountPtr< const char >
261 Kernel::InsertionContinuation::description( ) const
263 return strrefdup( "insertion" );
266 void
267 Kernel::InsertionContinuation::gcMark( Kernel::GCMarkedSet & marked )
269 cont_->gcMark( marked );
270 dyn_->gcMark( marked );
274 Kernel::StmtStoreValueContinuation::StmtStoreValueContinuation( Kernel::ValueRef * res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
275 : Kernel::Continuation( traceLoc ), res_( res ), cont_( cont )
278 Kernel::StmtStoreValueContinuation::~StmtStoreValueContinuation( )
281 void
282 Kernel::StmtStoreValueContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
284 *res_ = val;
285 evalState->cont_ = cont_;
286 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
289 Kernel::ContRef
290 Kernel::StmtStoreValueContinuation::up( ) const
292 return cont_;
295 RefCountPtr< const char >
296 Kernel::StmtStoreValueContinuation::description( ) const
298 return strrefdup( "statement store (value)" );
301 void
302 Kernel::StmtStoreValueContinuation::gcMark( Kernel::GCMarkedSet & marked )
304 cont_->gcMark( marked );
308 Kernel::StmtStoreVariableContinuation::StmtStoreVariableContinuation( const Kernel::VariableHandle & dst, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
309 : Kernel::Continuation( traceLoc ), dst_( dst ), cont_( cont )
312 Kernel::StmtStoreVariableContinuation::~StmtStoreVariableContinuation( )
315 void
316 Kernel::StmtStoreVariableContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
318 /* This class is friends with Variable, hence setValue is accessible. */
319 dst_->setValue( val );
320 evalState->cont_ = cont_;
321 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
324 Kernel::ContRef
325 Kernel::StmtStoreVariableContinuation::up( ) const
327 return cont_;
330 RefCountPtr< const char >
331 Kernel::StmtStoreVariableContinuation::description( ) const
333 return strrefdup( "statement store (variable)" );
336 void
337 Kernel::StmtStoreVariableContinuation::gcMark( Kernel::GCMarkedSet & marked )
339 dst_->gcMark( marked );
340 cont_->gcMark( marked );
345 Kernel::ForcingContinuation::ForcingContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
346 : Kernel::Continuation( traceLoc ), cont_( cont )
349 Kernel::ForcingContinuation::~ForcingContinuation( )
352 void
353 Kernel::ForcingContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
355 /* The reason for using this is simply that it only takes values. Then, the value
356 * is passed to whatever surrounding continuation.
358 evalState->cont_ = cont_;
359 cont_->takeValue( val, evalState );
362 Kernel::ContRef
363 Kernel::ForcingContinuation::up( ) const
365 return cont_;
368 RefCountPtr< const char >
369 Kernel::ForcingContinuation::description( ) const
371 return strrefdup( "force evaluation" );
374 void
375 Kernel::ForcingContinuation::gcMark( Kernel::GCMarkedSet & marked )
377 cont_->gcMark( marked );
381 Kernel::ForcingListContinuation::ForcingListContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc, bool forceStructures, bool consify )
382 : Kernel::Continuation( traceLoc ), cont_( cont ), forceStructures_( forceStructures ), consify_( consify ), index_( 0 ), pile_( Lang::THE_CONS_NULL )
385 Kernel::ForcingListContinuation::ForcingListContinuation( bool forceStructures, bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
386 : Kernel::Continuation( traceLoc ), cont_( cont ), forceStructures_( forceStructures ), consify_( consify ), index_( index ), pile_( pile )
389 Kernel::ForcingListContinuation::~ForcingListContinuation( )
392 void
393 Kernel::ForcingListContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
396 RefCountPtr< const Lang::SingleList > rest = val.down_cast< const Lang::SingleList >( );
397 if( rest != NullPtr< const Lang::SingleList >( ) ){
398 RefCountPtr< const Lang::SingleList > pile = pile_;
399 RefCountPtr< const Lang::SingleList > result = Lang::THE_CONS_NULL;
401 typedef const Lang::SingleListPair PairType;
402 PairType * p = dynamic_cast< PairType * >( rest.getPtr( ) );
403 if( p != 0 )
405 if( index_ == 0 && p->isForced( ) ){
406 /* Efficient code should end up here most of the time. */
407 if( ! forceStructures_ ){
408 evalState->cont_ = cont_;
409 cont_->takeValue( val, evalState );
410 return;
413 size_t index = index_;
414 while( p != 0 ){
415 if( p->car_->isThunk( ) ){
416 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListCarContinuation( forceStructures_, consify_, index, p->cdr_, pile, cont_, traceLoc_ ) );
417 Kernel::VariableHandle carCopy = p->car_.unconst_cast< Kernel::Variable >( );
418 carCopy->force( carCopy, evalState );
419 return;
421 RefCountPtr< const Lang::Value > carVal = p->car_->getUntyped( );
422 if( forceStructures_ && carVal.down_cast< const Lang::Structure >( ) != NullPtr< const Lang::Structure >( ) ){
423 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListCarStructureContinuation( consify_, index, p->cdr_, pile, cont_, traceLoc_ ) );
424 Kernel::ContRef cont = evalState->cont_;
425 cont->takeValue( carVal, evalState );
426 return;
428 pile = Helpers::SingleList_cons( carVal, pile );
429 rest = p->cdr_;
430 p = dynamic_cast< PairType * >( rest.getPtr( ) );
431 ++index;
435 if( rest->isNull( ) ){
436 goto reverse;
440 typedef const Lang::SingleListRange< const Lang::Integer > SpanType;
441 RefCountPtr< SpanType > span = rest.down_cast< SpanType >( );
442 if( span != NullPtr< SpanType >( ) )
444 if( index_ == 0 && ! consify_ ){
445 evalState->cont_ = cont_;
446 cont_->takeValue( val, evalState ); /* val and rest are the same since index is 0. */
447 return;
449 if( consify_ ){
450 result = span->consify( );
451 }else{
452 result = span;
454 goto reverse;
458 typedef const Lang::SingleListRange< const Lang::Float > SpanType;
459 RefCountPtr< SpanType > span = rest.down_cast< SpanType >( );
460 if( span != NullPtr< SpanType >( ) )
462 if( index_ == 0 && ! consify_ ){
463 evalState->cont_ = cont_;
464 cont_->takeValue( val, evalState ); /* val and rest are the same since index is 0. */
465 return;
467 if( consify_ ){
468 result = span->consify( );
469 }else{
470 result = span;
472 goto reverse;
476 typedef const Lang::SingleListRange< const Lang::Length > SpanType;
477 RefCountPtr< SpanType > span = rest.down_cast< SpanType >( );
478 if( span != NullPtr< SpanType >( ) )
480 if( index_ == 0 && ! consify_ ){
481 evalState->cont_ = cont_;
482 cont_->takeValue( val, evalState ); /* val and rest are the same since index is 0. */
483 return;
485 if( consify_ ){
486 result = span->consify( );
487 }else{
488 result = span;
490 goto reverse;
494 throw Exceptions::InternalError( "Kernel::ForcingListContinuation::takeValue: Uncovered subtype of SingleList." );
496 reverse:
497 /* We're done forcing. Reverse the accumulated result. */
499 typedef const Lang::SingleListPair PairType;
500 PairType * pTyped = dynamic_cast< PairType * >( pile.getPtr( ) );
501 while( pTyped != 0 ){
502 result = RefCountPtr< const Lang::SingleListPair >( new Lang::SingleListPair( pTyped->car_, result ) );
503 pTyped = dynamic_cast< PairType * >( pTyped->cdr_.getPtr( ) );
506 evalState->cont_ = cont_;
507 cont_->takeValue( result, evalState );
508 return;
513 typedef const Lang::ConsPair PairType;
514 PairType * p = dynamic_cast< PairType * >( val.getPtr( ) );
515 if( p != 0 )
517 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingConsCarContinuation( forceStructures_, consify_, index_, p->cdr( ), pile_, cont_, traceLoc_ ) );
518 Kernel::VariableHandle carCopy = p->car( ).unconst_cast< Kernel::Variable >( );
519 carCopy->force( carCopy, evalState );
520 return;
524 throw Exceptions::ExpectedList( traceLoc_, index_, val->getTypeName( ) );
527 Kernel::ContRef
528 Kernel::ForcingListContinuation::up( ) const
530 return cont_;
533 RefCountPtr< const char >
534 Kernel::ForcingListContinuation::description( ) const
536 return strrefdup( "force all elements in list" );
539 void
540 Kernel::ForcingListContinuation::gcMark( Kernel::GCMarkedSet & marked )
542 cont_->gcMark( marked );
543 const_cast< Lang::SingleList * >( pile_.getPtr( ) )->gcMark( marked );
547 Kernel::ForcingListCarContinuation::ForcingListCarContinuation( bool forceStructures, bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
548 : Kernel::Continuation( traceLoc ), cont_( cont ), forceStructures_( forceStructures ), consify_( consify ), index_( index ), cdr_( cdr ), pile_( pile )
551 Kernel::ForcingListCarContinuation::~ForcingListCarContinuation( )
554 void
555 Kernel::ForcingListCarContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
557 if( forceStructures_ && val.down_cast< const Lang::Structure >( ) != NullPtr< const Lang::Structure >( ) ){
558 Kernel::ContRef cont = Kernel::ContRef( new Kernel::ForcingListCarStructureContinuation( consify_, index_, cdr_, pile_, cont_, traceLoc_ ) );
559 evalState->cont_ = cont;
560 cont->takeValue( val, evalState );
561 return;
564 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListContinuation( forceStructures_, consify_, index_ + 1, Helpers::SingleList_cons( val, pile_ ), cont_, traceLoc_ ) );
565 Kernel::ContRef cont = evalState->cont_;
566 cont->takeValue( cdr_, evalState );
569 Kernel::ContRef
570 Kernel::ForcingListCarContinuation::up( ) const
572 return cont_;
575 RefCountPtr< const char >
576 Kernel::ForcingListCarContinuation::description( ) const
578 return strrefdup( "force element in list (singly linked)" );
581 void
582 Kernel::ForcingListCarContinuation::gcMark( Kernel::GCMarkedSet & marked )
584 const_cast< Lang::SingleList * >( cdr_.getPtr( ) )->gcMark( marked );
585 const_cast< Lang::SingleList * >( pile_.getPtr( ) )->gcMark( marked );
586 cont_->gcMark( marked );
589 Kernel::ForcingListCarStructureContinuation::ForcingListCarStructureContinuation( bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
590 : Kernel::ForcedStructureContinuation( "Forcing structures in list (singly linked)", traceLoc ), cont_( cont ), consify_( consify ), index_( index ), cdr_( cdr ), pile_( pile )
593 Kernel::ForcingListCarStructureContinuation::~ForcingListCarStructureContinuation( )
596 void
597 Kernel::ForcingListCarStructureContinuation::takeStructure( const RefCountPtr< const Lang::Structure > & structure, Kernel::EvalState * evalState ) const
599 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListContinuation( true, consify_, index_ + 1, Helpers::SingleList_cons( structure, pile_ ), cont_, traceLoc_ ) );
600 Kernel::ContRef cont = evalState->cont_;
601 cont->takeValue( cdr_, evalState );
604 Kernel::ContRef
605 Kernel::ForcingListCarStructureContinuation::up( ) const
607 return cont_;
610 RefCountPtr< const char >
611 Kernel::ForcingListCarStructureContinuation::description( ) const
613 return strrefdup( "force structure element in list (singly linked)" );
616 void
617 Kernel::ForcingListCarStructureContinuation::gcMark( Kernel::GCMarkedSet & marked )
619 const_cast< Lang::SingleList * >( cdr_.getPtr( ) )->gcMark( marked );
620 const_cast< Lang::SingleList * >( pile_.getPtr( ) )->gcMark( marked );
621 cont_->gcMark( marked );
624 Kernel::ForcingConsCarContinuation::ForcingConsCarContinuation( bool forceStructures, bool consify, size_t index, const Kernel::VariableHandle & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
625 : Kernel::Continuation( traceLoc ), cont_( cont ), forceStructures_( forceStructures ), consify_( consify ), index_( index ), cdr_( cdr ), pile_( pile )
628 Kernel::ForcingConsCarContinuation::~ForcingConsCarContinuation( )
631 void
632 Kernel::ForcingConsCarContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
634 if( forceStructures_ && val.down_cast< const Lang::Structure >( ) != NullPtr< const Lang::Structure >( ) ){
635 Kernel::ContRef cont = Kernel::ContRef( new Kernel::ForcingConsCarStructureContinuation( consify_, index_, cdr_, pile_, cont_, traceLoc_ ) );
636 evalState->cont_ = cont;
637 cont->takeValue( val, evalState );
638 return;
641 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListContinuation( forceStructures_, consify_, index_ + 1, Helpers::SingleList_cons( val, pile_ ), cont_, traceLoc_ ) );
642 Kernel::VariableHandle cdrCopy = cdr_.unconst_cast< Kernel::Variable >( );
643 cdrCopy->force( cdrCopy, evalState );
646 Kernel::ContRef
647 Kernel::ForcingConsCarContinuation::up( ) const
649 return cont_;
652 RefCountPtr< const char >
653 Kernel::ForcingConsCarContinuation::description( ) const
655 return strrefdup( "force element in list (cons)" );
658 void
659 Kernel::ForcingConsCarContinuation::gcMark( Kernel::GCMarkedSet & marked )
661 cdr_.getPtr( )->gcMark( marked );
662 const_cast< Lang::SingleList * >( pile_.getPtr( ) )->gcMark( marked );
663 cont_->gcMark( marked );
666 Kernel::ForcingConsCarStructureContinuation::ForcingConsCarStructureContinuation( bool consify, size_t index, const Kernel::VariableHandle & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
667 : Kernel::ForcedStructureContinuation( "Forcing structures in list (cons list)", traceLoc ), cont_( cont ), consify_( consify ), index_( index ), cdr_( cdr ), pile_( pile )
670 Kernel::ForcingConsCarStructureContinuation::~ForcingConsCarStructureContinuation( )
673 void
674 Kernel::ForcingConsCarStructureContinuation::takeStructure( const RefCountPtr< const Lang::Structure > & structure, Kernel::EvalState * evalState ) const
676 evalState->cont_ = Kernel::ContRef( new Kernel::ForcingListContinuation( true, consify_, index_ + 1, Helpers::SingleList_cons( structure, pile_ ), cont_, traceLoc_ ) );
677 Kernel::VariableHandle cdrCopy = cdr_.unconst_cast< Kernel::Variable >( );
678 cdrCopy->force( cdrCopy, evalState );
681 Kernel::ContRef
682 Kernel::ForcingConsCarStructureContinuation::up( ) const
684 return cont_;
687 RefCountPtr< const char >
688 Kernel::ForcingConsCarStructureContinuation::description( ) const
690 return strrefdup( "force structure element in list (cons)" );
693 void
694 Kernel::ForcingConsCarStructureContinuation::gcMark( Kernel::GCMarkedSet & marked )
696 cdr_.getPtr( )->gcMark( marked );
697 const_cast< Lang::SingleList * >( pile_.getPtr( ) )->gcMark( marked );
698 cont_->gcMark( marked );
702 Kernel::ExitContinuation::ExitContinuation( bool * done, const Ast::SourceLocation & traceLoc )
703 : Kernel::Continuation( traceLoc ), done_( done )
706 Kernel::ExitContinuation::~ExitContinuation( )
709 void
710 Kernel::ExitContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
712 *done_ = true;
715 Kernel::ContRef
716 Kernel::ExitContinuation::up( ) const
718 return Kernel::ContRef( NullPtr< Kernel::Continuation >( ) );
721 RefCountPtr< const char >
722 Kernel::ExitContinuation::description( ) const
724 return strrefdup( "exit (non-forcing)" );
727 void
728 Kernel::ExitContinuation::gcMark( Kernel::GCMarkedSet & marked )
732 Kernel::DefaultErrorContinuation::DefaultErrorContinuation( const Ast::SourceLocation & traceLoc )
733 : Kernel::Continuation( traceLoc )
736 Kernel::DefaultErrorContinuation::~DefaultErrorContinuation( )
739 void
740 Kernel::DefaultErrorContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
742 throw Exceptions::UncaughtError( Helpers::down_cast_ContinuationArgument< const Lang::Exception >( val, this ) );
745 Kernel::ContRef
746 Kernel::DefaultErrorContinuation::up( ) const
748 return Kernel::ContRef( NullPtr< Kernel::Continuation >( ) );
751 RefCountPtr< const char >
752 Kernel::DefaultErrorContinuation::description( ) const
754 return strrefdup( "default error continuation" );
757 void
758 Kernel::DefaultErrorContinuation::gcMark( Kernel::GCMarkedSet & marked )
762 Kernel::Transform2DCont::Transform2DCont( Lang::Transform2D tf, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
763 : Kernel::Continuation( traceLoc ), tf_( tf ), cont_( cont )
766 Kernel::Transform2DCont::~Transform2DCont( )
769 void
770 Kernel::Transform2DCont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
774 typedef const Lang::Geometric2D ArgType;
775 RefCountPtr< ArgType > arg = Helpers::try_cast_CoreArgument< ArgType >( val );
776 evalState->cont_ = cont_;
777 cont_->takeValue( arg->transformed( tf_, arg ),
778 evalState );
779 return;
781 catch( const NonLocalExit::NotThisType & ball )
783 /* Wrong type; never mind!.. but see below!
789 typedef const Lang::FloatPair ArgType;
790 RefCountPtr< ArgType > arg = Helpers::try_cast_CoreArgument< ArgType >( val );
791 evalState->cont_ = cont_;
792 cont_->takeValue( arg->transformed( tf_ ),
793 evalState );
794 return;
796 catch( const NonLocalExit::NotThisType & ball )
798 /* Wrong type; never mind!.. but see below!
802 throw Exceptions::ContinuationTypeMismatch( this, val->getTypeName( ), Helpers::typeSetString( Lang::Geometric2D::staticTypeName( ), Lang::FloatPair::staticTypeName( ) ) );
805 Kernel::ContRef
806 Kernel::Transform2DCont::up( ) const
808 return cont_;
811 RefCountPtr< const char >
812 Kernel::Transform2DCont::description( ) const
814 return strrefdup( "2D transform application" );
817 void
818 Kernel::Transform2DCont::gcMark( Kernel::GCMarkedSet & marked )
820 cont_->gcMark( marked );
824 Kernel::Transform3DCont::Transform3DCont( Lang::Transform3D tf, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
825 : Kernel::Continuation( traceLoc ), tf_( tf ), cont_( cont )
828 Kernel::Transform3DCont::~Transform3DCont( )
831 void
832 Kernel::Transform3DCont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
836 typedef const Lang::Geometric3D ArgType;
837 RefCountPtr< ArgType > arg = Helpers::try_cast_CoreArgument< ArgType >( val );
838 evalState->cont_ = cont_;
839 cont_->takeValue( arg->transformed( tf_, arg ),
840 evalState );
841 return;
843 catch( const NonLocalExit::NotThisType & ball )
845 /* Wrong type; never mind!.. but see below!
851 typedef const Lang::FloatTriple ArgType;
852 RefCountPtr< ArgType > arg = Helpers::try_cast_CoreArgument< ArgType >( val );
853 evalState->cont_ = cont_;
854 cont_->takeValue( arg->transformed( tf_ ),
855 evalState );
856 return;
858 catch( const NonLocalExit::NotThisType & ball )
860 /* Wrong type; never mind!.. but see below!
864 throw Exceptions::ContinuationTypeMismatch( this, val->getTypeName( ), Helpers::typeSetString( Lang::Geometric3D::staticTypeName( ), Lang::FloatTriple::staticTypeName( ) ) );
867 Kernel::ContRef
868 Kernel::Transform3DCont::up( ) const
870 return cont_;
873 RefCountPtr< const char >
874 Kernel::Transform3DCont::description( ) const
876 return strrefdup( "3D transform application" );
879 void
880 Kernel::Transform3DCont::gcMark( Kernel::GCMarkedSet & marked )
882 cont_->gcMark( marked );
886 Kernel::PathApplication2DCont::PathApplication2DCont( RefCountPtr< const Lang::ElementaryPath2D > path, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
887 : Kernel::Continuation( traceLoc ), path_( path ), cont_( cont )
890 Kernel::PathApplication2DCont::~PathApplication2DCont( )
893 void
894 Kernel::PathApplication2DCont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
896 Concrete::SplineTime t = Helpers::pathTimeCast( path_.getPtr( ), val.getPtr( ), this );
898 evalState->cont_ = cont_;
899 cont_->takeValue( Kernel::ValueRef( new Lang::PathSlider2D( path_, t.t( ) ) ),
900 evalState );
901 return;
904 Kernel::ContRef
905 Kernel::PathApplication2DCont::up( ) const
907 return cont_;
910 RefCountPtr< const char >
911 Kernel::PathApplication2DCont::description( ) const
913 return strrefdup( "2D path point selection" );
916 void
917 Kernel::PathApplication2DCont::gcMark( Kernel::GCMarkedSet & marked )
919 const_cast< Lang::ElementaryPath2D * >( path_.getPtr( ) )->gcMark( marked );
920 cont_->gcMark( marked );
924 Kernel::PathApplication3DCont::PathApplication3DCont( RefCountPtr< const Lang::ElementaryPath3D > path, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc )
925 : Kernel::Continuation( traceLoc ), path_( path ), cont_( cont )
928 Kernel::PathApplication3DCont::~PathApplication3DCont( )
931 void
932 Kernel::PathApplication3DCont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
934 Concrete::SplineTime t = Helpers::pathTimeCast( path_.getPtr( ), val.getPtr( ), this );
936 evalState->cont_ = cont_;
937 cont_->takeValue( Kernel::ValueRef( new Lang::PathSlider3D( path_, t.t( ) ) ),
938 evalState );
939 return;
942 Kernel::ContRef
943 Kernel::PathApplication3DCont::up( ) const
945 return cont_;
948 RefCountPtr< const char >
949 Kernel::PathApplication3DCont::description( ) const
951 return strrefdup( "3D path point selection" );
954 void
955 Kernel::PathApplication3DCont::gcMark( Kernel::GCMarkedSet & marked )
957 const_cast< Lang::ElementaryPath3D * >( path_.getPtr( ) )->gcMark( marked );
958 cont_->gcMark( marked );
962 Kernel::ComposedFunctionCall_cont::ComposedFunctionCall_cont( const RefCountPtr< const Lang::Function > & second, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
963 : Kernel::Continuation( callLoc ), second_( second ), dyn_( dyn ), cont_( cont )
966 Kernel::ComposedFunctionCall_cont::~ComposedFunctionCall_cont( )
969 void
970 Kernel::ComposedFunctionCall_cont::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
972 evalState->dyn_ = dyn_;
973 evalState->cont_ = cont_;
974 second_->call( second_, evalState, val, traceLoc_ );
977 Kernel::ContRef
978 Kernel::ComposedFunctionCall_cont::up( ) const
980 return cont_;
983 RefCountPtr< const char >
984 Kernel::ComposedFunctionCall_cont::description( ) const
986 return strrefdup( "composed function's second application" );
989 void
990 Kernel::ComposedFunctionCall_cont::gcMark( Kernel::GCMarkedSet & marked )
992 const_cast< Lang::Function * >( second_.getPtr( ) )->gcMark( marked );
993 dyn_->gcMark( marked );
994 cont_->gcMark( marked );
998 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 )
999 : Kernel::Continuation( callLoc ), arg1_( arg1 ), arg2_( arg2 ), dyn_( dyn ), cont_( cont )
1002 Kernel::ForceFunctionAndCall_2_args_cont::~ForceFunctionAndCall_2_args_cont( )
1005 void
1006 Kernel::ForceFunctionAndCall_2_args_cont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
1008 evalState->dyn_ = dyn_;
1009 evalState->cont_ = cont_;
1010 typedef const Lang::Function ArgType;
1011 RefCountPtr< ArgType > fun( Helpers::down_cast_ContinuationArgument< ArgType >( val, this ) );
1012 fun->call( fun, evalState, arg1_, arg2_, traceLoc_ );
1015 Kernel::ContRef
1016 Kernel::ForceFunctionAndCall_2_args_cont::up( ) const
1018 return cont_;
1021 RefCountPtr< const char >
1022 Kernel::ForceFunctionAndCall_2_args_cont::description( ) const
1024 return strrefdup( "call function with two values" );
1027 void
1028 Kernel::ForceFunctionAndCall_2_args_cont::gcMark( Kernel::GCMarkedSet & marked )
1030 arg1_->gcMark( marked );
1031 arg2_->gcMark( marked );
1032 dyn_->gcMark( marked );
1033 cont_->gcMark( marked );
1037 Kernel::RelaxContinuation::RelaxContinuation( Kernel::ContRef & cont )
1038 : Kernel::Continuation( cont->traceLoc( ) ), cont_( cont )
1041 Kernel::RelaxContinuation::~RelaxContinuation( )
1044 void
1045 Kernel::RelaxContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
1047 evalState->cont_ = cont_;
1048 Helpers::relax( val, evalState );
1051 Kernel::ContRef
1052 Kernel::RelaxContinuation::up( ) const
1054 return cont_;
1057 RefCountPtr< const char >
1058 Kernel::RelaxContinuation::description( ) const
1060 return strrefdup( "relax" );
1063 void
1064 Kernel::RelaxContinuation::gcMark( Kernel::GCMarkedSet & marked )
1066 cont_->gcMark( marked );