Example: Changed glyph-outline.shape for use with FontConfig.
[shapes.git] / source / continuations.cc
blob26825fd620d979d38f0f7b2870ad3188922fa395
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 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 );
139 Kernel::ContRef
140 Kernel::IntroduceStateContinuation::up( ) const
142 return cont_;
145 RefCountPtr< const char >
146 Kernel::IntroduceStateContinuation::description( ) const
148 return strrefdup( "introduce warm" );
151 void
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( )
166 void
167 Kernel::StoreValueContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
169 if( val->isThunk( ) )
171 val->force( val, evalState );
173 else
175 *res_ = val->getUntyped( );
176 evalState->cont_ = cont_;
177 cont_->takeHandle( val, evalState );
181 Kernel::ContRef
182 Kernel::StoreValueContinuation::up( ) const
184 return cont_;
187 RefCountPtr< const char >
188 Kernel::StoreValueContinuation::description( ) const
190 return strrefdup( "store and return" );
193 void
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( )
207 void
208 Kernel::StoreVariableContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
210 if( val->isThunk( ) )
212 val->force( val, evalState );
214 else
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 );
223 Kernel::ContRef
224 Kernel::StoreVariableContinuation::up( ) const
226 return cont_;
229 RefCountPtr< const char >
230 Kernel::StoreVariableContinuation::description( ) const
232 return strrefdup( "store and return" );
235 void
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( )
250 void
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_ );
258 Kernel::ContRef
259 Kernel::InsertionContinuation::up( ) const
261 return cont_;
264 RefCountPtr< const char >
265 Kernel::InsertionContinuation::description( ) const
267 return strrefdup( "insertion" );
270 void
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( )
285 void
286 Kernel::StmtStoreValueContinuation::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
288 *res_ = val;
289 evalState->cont_ = cont_;
290 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
293 Kernel::ContRef
294 Kernel::StmtStoreValueContinuation::up( ) const
296 return cont_;
299 RefCountPtr< const char >
300 Kernel::StmtStoreValueContinuation::description( ) const
302 return strrefdup( "statement store (value)" );
305 void
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( )
319 void
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 );
328 Kernel::ContRef
329 Kernel::StmtStoreVariableContinuation::up( ) const
331 return cont_;
334 RefCountPtr< const char >
335 Kernel::StmtStoreVariableContinuation::description( ) const
337 return strrefdup( "statement store (variable)" );
340 void
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( )
356 void
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 );
366 Kernel::ContRef
367 Kernel::ForcingContinuation::up( ) const
369 return cont_;
372 RefCountPtr< const char >
373 Kernel::ForcingContinuation::description( ) const
375 return strrefdup( "force evaluation" );
378 void
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( )
392 void
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( ) );
398 if( p == 0 )
400 /* We're done! */
401 evalState->cont_ = cont_;
402 cont_->takeHandle( Kernel::THE_VOID_VARIABLE, evalState );
403 return;
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 );
410 Kernel::ContRef
411 Kernel::ForcingSingleListContinuation::up( ) const
413 return cont_;
416 RefCountPtr< const char >
417 Kernel::ForcingSingleListContinuation::description( ) const
419 return strrefdup( "force entire SingleList" );
422 void
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( )
437 void
438 Kernel::ExitContinuation::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
440 *done_ = true;
443 Kernel::ContRef
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)" );
455 void
456 Kernel::ExitContinuation::gcMark( Kernel::GCMarkedSet & marked )
460 Kernel::DefaultErrorContinuation::DefaultErrorContinuation( const Ast::SourceLocation & traceLoc )
461 : Kernel::Continuation( traceLoc )
464 Kernel::DefaultErrorContinuation::~DefaultErrorContinuation( )
467 void
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 ) );
473 Kernel::ContRef
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" );
485 void
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( )
497 void
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 ),
506 evalState );
507 return;
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_ ),
521 evalState );
522 return;
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( ) ) );
533 Kernel::ContRef
534 Kernel::Transform2DCont::up( ) const
536 return cont_;
539 RefCountPtr< const char >
540 Kernel::Transform2DCont::description( ) const
542 return strrefdup( "2D transform application" );
545 void
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( )
559 void
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 ),
568 evalState );
569 return;
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_ ),
583 evalState );
584 return;
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( ) ) );
595 Kernel::ContRef
596 Kernel::Transform3DCont::up( ) const
598 return cont_;
601 RefCountPtr< const char >
602 Kernel::Transform3DCont::description( ) const
604 return strrefdup( "3D transform application" );
607 void
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( )
621 void
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( ) ) ),
628 evalState );
629 return;
632 Kernel::ContRef
633 Kernel::PathApplication2DCont::up( ) const
635 return cont_;
638 RefCountPtr< const char >
639 Kernel::PathApplication2DCont::description( ) const
641 return strrefdup( "2D path point selection" );
644 void
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( )
659 void
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( ) ) ),
666 evalState );
667 return;
670 Kernel::ContRef
671 Kernel::PathApplication3DCont::up( ) const
673 return cont_;
676 RefCountPtr< const char >
677 Kernel::PathApplication3DCont::description( ) const
679 return strrefdup( "3D path point selection" );
682 void
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( )
697 void
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_ );
705 Kernel::ContRef
706 Kernel::ComposedFunctionCall_cont::up( ) const
708 return cont_;
711 RefCountPtr< const char >
712 Kernel::ComposedFunctionCall_cont::description( ) const
714 return strrefdup( "composed function's second application" );
717 void
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( )
733 void
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_ );
743 Kernel::ContRef
744 Kernel::ForceFunctionAndCall_2_args_cont::up( ) const
746 return cont_;
749 RefCountPtr< const char >
750 Kernel::ForceFunctionAndCall_2_args_cont::description( ) const
752 return strrefdup( "call function with two values" );
755 void
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 );