Update procedures
[shapes.git] / source / containertypes.cc
blob164d904ff3bfaefa59ecd3a18103c19024a452f0
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, 2010, 2013 Henrik Tidefelt
19 #include "shapestypes.h"
20 #include "shapesexceptions.h"
21 #include "astexpr.h"
22 #include "continuations.h"
23 #include "consts.h"
24 #include "angleselect.h"
25 #include "astvar.h"
26 #include "astclass.h"
27 #include "globals.h"
28 #include "methodbase.h"
29 #include "functiontypes.h" /* So that we can set up methods for VectorFunction, which is a kind of container too. */
31 using namespace Shapes;
34 namespace Shapes
36 namespace Lang
39 template< class T >
40 class Method_foldl : public Lang::MethodBase< T >
42 public:
43 Method_foldl( RefCountPtr< const T > _self, const Ast::FileID * fullMethodID );
44 virtual ~Method_foldl( );
45 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
46 static const char * staticFieldID( ) { return "foldl"; }
49 template< class T >
50 class Method_foldr : public Lang::MethodBase< T >
52 public:
53 Method_foldr( RefCountPtr< const T > _self, const Ast::FileID * fullMethodID );
54 virtual ~Method_foldr( );
55 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
56 static const char * staticFieldID( ) { return "foldr"; }
59 template< class T >
60 class Method_foldsl : public Lang::MethodBase< T >
62 public:
63 Method_foldsl( RefCountPtr< const T > _self, const Ast::FileID * fullMethodID );
64 virtual ~Method_foldsl( );
65 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
66 static const char * staticFieldID( ) { return "foldsl"; }
69 template< class T >
70 class Method_foldsr : public Lang::MethodBase< T >
72 public:
73 Method_foldsr( RefCountPtr< const T > _self, const Ast::FileID * fullMethodID );
74 virtual ~Method_foldsr( );
75 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
76 static const char * staticFieldID( ) { return "foldsr"; }
81 namespace Kernel
84 class ForceFunctionAndCall_2_args_1_state_cont : public Kernel::Continuation
86 Kernel::VariableHandle arg1_;
87 Kernel::VariableHandle arg2_;
88 Kernel::StateHandle state_;
89 Kernel::PassedDyn dyn_;
90 Kernel::ContRef cont_;
91 public:
92 ForceFunctionAndCall_2_args_1_state_cont( const Kernel::VariableHandle & arg1, const Kernel::VariableHandle & arg2, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc );
93 virtual ~ForceFunctionAndCall_2_args_1_state_cont( );
94 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
95 virtual Kernel::ContRef up( ) const;
96 virtual RefCountPtr< const char > description( ) const;
97 virtual void gcMark( Kernel::GCMarkedSet & marked );
104 Lang::SingleList::SingleList( )
107 Lang::SingleList::~SingleList( )
110 void
111 SingleList_register_methods( Lang::SystemFinalClass * dstClass )
113 dstClass->registerMethod( new Kernel::MethodFactory< Lang::SingleList, Lang::Method_foldl< Lang::SingleList > >( ) );
114 dstClass->registerMethod( new Kernel::MethodFactory< Lang::SingleList, Lang::Method_foldr< Lang::SingleList > >( ) );
115 dstClass->registerMethod( new Kernel::MethodFactory< Lang::SingleList, Lang::Method_foldsl< Lang::SingleList > >( ) );
116 dstClass->registerMethod( new Kernel::MethodFactory< Lang::SingleList, Lang::Method_foldsr< Lang::SingleList > >( ) );
119 RefCountPtr< const Lang::Class > Lang::SingleList::TypeID( new Lang::SystemFinalClass( strrefdup( "SeqPair" ), SingleList_register_methods ) );
120 TYPEINFOIMPL( SingleList );
122 Kernel::VariableHandle
123 Lang::SingleList::getField( const char * fieldId, const RefCountPtr< const Lang::Value > & selfRef ) const
125 return TypeID->getMethod( selfRef, fieldId ); /* This will throw if there is no such method. */
129 Kernel::SingleFoldLCont::SingleFoldLCont( const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::Function > & op, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
130 : Kernel::Continuation( traceLoc ), cdr_( cdr ), op_( op ), dyn_( dyn ), cont_( cont )
133 Kernel::SingleFoldLCont::~SingleFoldLCont( )
136 void
137 Kernel::SingleFoldLCont::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
139 evalState->dyn_ = dyn_;
140 evalState->cont_ = cont_;
141 cdr_->foldl( evalState, op_, val, traceLoc_ );
144 Kernel::ContRef
145 Kernel::SingleFoldLCont::up( ) const
147 return cont_;
150 RefCountPtr< const char >
151 Kernel::SingleFoldLCont::description( ) const
153 return strrefdup( "singly linked list's foldl" );
156 void
157 Kernel::SingleFoldLCont::gcMark( Kernel::GCMarkedSet & marked )
159 const_cast< Lang::SingleList * >( cdr_.getPtr( ) )->gcMark( marked );
160 const_cast< Lang::Function * >( op_.getPtr( ) )->gcMark( marked );
161 dyn_->gcMark( marked );
162 cont_->gcMark( marked );
166 Kernel::SingleFoldRCont::SingleFoldRCont( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::Function > & op, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
167 : Kernel::Continuation( traceLoc ), car_( car ), op_( op ), dyn_( dyn ), cont_( cont )
170 Kernel::SingleFoldRCont::~SingleFoldRCont( )
173 void
174 Kernel::SingleFoldRCont::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
176 evalState->dyn_ = dyn_;
177 evalState->cont_ = cont_;
178 op_->call( op_, evalState, car_, val, traceLoc_ );
181 Kernel::ContRef
182 Kernel::SingleFoldRCont::up( ) const
184 return cont_;
187 RefCountPtr< const char >
188 Kernel::SingleFoldRCont::description( ) const
190 return strrefdup( "foldr" );
193 void
194 Kernel::SingleFoldRCont::gcMark( Kernel::GCMarkedSet & marked )
196 car_->gcMark( marked );
197 const_cast< Lang::Function * >( op_.getPtr( ) )->gcMark( marked );
198 dyn_->gcMark( marked );
199 cont_->gcMark( marked );
203 Kernel::SingleFoldSLCont::SingleFoldSLCont( const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::Function > & op, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
204 : Kernel::Continuation( traceLoc ), cdr_( cdr ), op_( op ), state_( state ), dyn_( dyn ), cont_( cont )
207 Kernel::SingleFoldSLCont::~SingleFoldSLCont( )
210 void
211 Kernel::SingleFoldSLCont::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
213 evalState->dyn_ = dyn_;
214 evalState->cont_ = cont_;
215 cdr_->foldsl( evalState, op_, val, state_, traceLoc_ );
218 Kernel::ContRef
219 Kernel::SingleFoldSLCont::up( ) const
221 return cont_;
224 RefCountPtr< const char >
225 Kernel::SingleFoldSLCont::description( ) const
227 return strrefdup( "singly linked list's foldsl" );
230 void
231 Kernel::SingleFoldSLCont::gcMark( Kernel::GCMarkedSet & marked )
233 const_cast< Lang::SingleList * >( cdr_.getPtr( ) )->gcMark( marked );
234 const_cast< Lang::Function * >( op_.getPtr( ) )->gcMark( marked );
235 state_->gcMark( marked );
236 dyn_->gcMark( marked );
237 cont_->gcMark( marked );
241 Kernel::SingleFoldSRCont::SingleFoldSRCont( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::Function > & op, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
242 : Kernel::Continuation( traceLoc ), car_( car ), op_( op ), state_( state ),dyn_( dyn ), cont_( cont )
245 Kernel::SingleFoldSRCont::~SingleFoldSRCont( )
248 void
249 Kernel::SingleFoldSRCont::takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
251 evalState->dyn_ = dyn_;
252 evalState->cont_ = cont_;
253 op_->call( op_, evalState, car_, val, state_, traceLoc_ );
256 Kernel::ContRef
257 Kernel::SingleFoldSRCont::up( ) const
259 return cont_;
262 RefCountPtr< const char >
263 Kernel::SingleFoldSRCont::description( ) const
265 return strrefdup( "foldsr" );
268 void
269 Kernel::SingleFoldSRCont::gcMark( Kernel::GCMarkedSet & marked )
271 car_->gcMark( marked );
272 const_cast< Lang::Function * >( op_.getPtr( ) )->gcMark( marked );
273 state_->gcMark( marked );
274 dyn_->gcMark( marked );
275 cont_->gcMark( marked );
279 namespace Shapes
281 namespace Kernel
284 class ConsPairFoldLCont_cdr : public Kernel::Continuation
286 Kernel::VariableHandle op_;
287 Kernel::VariableHandle nullResult_;
288 Kernel::PassedDyn dyn_;
289 Kernel::ContRef cont_;
290 public:
291 ConsPairFoldLCont_cdr( const Kernel::VariableHandle & op, const Kernel::VariableHandle & nullResult, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
292 : Kernel::Continuation( traceLoc ), op_( op ), nullResult_( nullResult ), dyn_( dyn ), cont_( cont )
294 virtual ~ConsPairFoldLCont_cdr( ) { }
295 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
297 evalState->dyn_ = dyn_;
298 evalState->cont_ = Kernel::ContRef( new Kernel::ForceFunctionAndCall_2_args_cont( op_, nullResult_, dyn_, cont_, traceLoc_ ) );
299 Kernel::VariableHandle fun = val->getField( "foldl", val );
300 fun->force( fun, evalState );
302 virtual Kernel::ContRef up( ) const
304 return cont_;
306 virtual RefCountPtr< const char > description( ) const
308 return strrefdup( "cons pair's foldl (force cdr)" );
310 virtual void gcMark( Kernel::GCMarkedSet & marked )
312 op_->gcMark( marked );
313 nullResult_->gcMark( marked );
314 dyn_->gcMark( marked );
315 cont_->gcMark( marked );
319 class ConsPairFoldLCont_op : public Kernel::Continuation
321 Kernel::VariableHandle cdr_;
322 Kernel::VariableHandle op_;
323 Kernel::PassedDyn dyn_;
324 Kernel::ContRef cont_;
325 public:
326 ConsPairFoldLCont_op( const Kernel::VariableHandle & cdr, const Kernel::VariableHandle & op, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
327 : Kernel::Continuation( traceLoc ), cdr_( cdr ), op_( op ), dyn_( dyn ), cont_( cont )
329 virtual ~ConsPairFoldLCont_op( ) { }
330 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
332 evalState->dyn_ = dyn_; /* Necessary?! */
333 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldLCont_cdr( op_, val, dyn_, cont_, traceLoc_ ) );
334 cdr_->force( cdr_, evalState );
336 virtual Kernel::ContRef up( ) const
338 return cont_;
340 virtual RefCountPtr< const char > description( ) const
342 return strrefdup( "cons pair's foldl (op)" );
344 virtual void gcMark( Kernel::GCMarkedSet & marked )
346 cdr_->gcMark( marked );
347 op_->gcMark( marked );
348 dyn_->gcMark( marked );
349 cont_->gcMark( marked );
353 class ConsPairFoldRCont_cdr : public Kernel::Continuation
355 Kernel::VariableHandle car_;
356 RefCountPtr< const Lang::Function > op_;
357 Kernel::VariableHandle opHandle_;
358 Kernel::VariableHandle nullResult_;
359 Kernel::PassedDyn dyn_;
360 Kernel::ContRef cont_;
361 public:
362 ConsPairFoldRCont_cdr( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
363 : Kernel::Continuation( traceLoc ), car_( car ), op_( op ), opHandle_( opHandle ), nullResult_( nullResult ), dyn_( dyn ), cont_( cont )
365 virtual ~ConsPairFoldRCont_cdr( ) { }
366 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
368 evalState->dyn_ = dyn_;
369 evalState->cont_ = Kernel::ContRef( new Kernel::ForceFunctionAndCall_2_args_cont( opHandle_, nullResult_, dyn_,
370 Kernel::ContRef( new Kernel::SingleFoldRCont( car_, op_, evalState->dyn_, cont_, traceLoc_ ) ),
371 traceLoc_ ) );
372 Kernel::VariableHandle fun = val->getField( "foldr", val );
373 fun->force( fun, evalState );
375 virtual Kernel::ContRef up( ) const
377 return cont_;
379 virtual RefCountPtr< const char > description( ) const
381 return strrefdup( "cons pair's foldl (force cdr)" );
383 virtual void gcMark( Kernel::GCMarkedSet & marked )
385 car_->gcMark( marked );
386 opHandle_->gcMark( marked ); /* This will gcMark op_ as well! */
387 nullResult_->gcMark( marked );
388 dyn_->gcMark( marked );
389 cont_->gcMark( marked );
393 class ConsPairFoldSLCont_cdr : public Kernel::Continuation
395 Kernel::VariableHandle op_;
396 Kernel::VariableHandle nullResult_;
397 Kernel::StateHandle state_;
398 Kernel::PassedDyn dyn_;
399 Kernel::ContRef cont_;
400 public:
401 ConsPairFoldSLCont_cdr( const Kernel::VariableHandle & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
402 : Kernel::Continuation( traceLoc ), op_( op ), nullResult_( nullResult ), state_( state ), dyn_( dyn ), cont_( cont )
404 virtual ~ConsPairFoldSLCont_cdr( ) { }
405 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
407 evalState->dyn_ = dyn_;
408 evalState->cont_ = Kernel::ContRef( new Kernel::ForceFunctionAndCall_2_args_1_state_cont( op_, nullResult_, state_, dyn_, cont_, traceLoc_ ) );
409 Kernel::VariableHandle fun = val->getField( "foldsl", val );
410 fun->force( fun, evalState );
412 virtual Kernel::ContRef up( ) const
414 return cont_;
416 virtual RefCountPtr< const char > description( ) const
418 return strrefdup( "cons pair's foldl (force cdr)" );
420 virtual void gcMark( Kernel::GCMarkedSet & marked )
422 op_->gcMark( marked );
423 nullResult_->gcMark( marked );
424 state_->gcMark( marked );
425 dyn_->gcMark( marked );
426 cont_->gcMark( marked );
430 class ConsPairFoldSLCont_op : public Kernel::Continuation
432 Kernel::VariableHandle cdr_;
433 Kernel::VariableHandle op_;
434 Kernel::StateHandle state_;
435 Kernel::PassedDyn dyn_;
436 Kernel::ContRef cont_;
437 public:
438 ConsPairFoldSLCont_op( const Kernel::VariableHandle & cdr, const Kernel::VariableHandle & op, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
439 : Kernel::Continuation( traceLoc ), cdr_( cdr ), op_( op ), state_( state ), dyn_( dyn ), cont_( cont )
441 virtual ~ConsPairFoldSLCont_op( ) { }
442 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const
444 evalState->dyn_ = dyn_; /* Necessary?! */
445 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldSLCont_cdr( op_, val, state_, dyn_, cont_, traceLoc_ ) );
446 cdr_->force( cdr_, evalState );
448 virtual Kernel::ContRef up( ) const
450 return cont_;
452 virtual RefCountPtr< const char > description( ) const
454 return strrefdup( "cons pair's foldl (op)" );
456 virtual void gcMark( Kernel::GCMarkedSet & marked )
458 cdr_->gcMark( marked );
459 op_->gcMark( marked );
460 state_->gcMark( marked );
461 dyn_->gcMark( marked );
462 cont_->gcMark( marked );
466 class ConsPairFoldSRCont_cdr : public Kernel::Continuation
468 Kernel::VariableHandle car_;
469 RefCountPtr< const Lang::Function > op_;
470 Kernel::VariableHandle opHandle_;
471 Kernel::VariableHandle nullResult_;
472 Kernel::StateHandle state_;
473 Kernel::PassedDyn dyn_;
474 Kernel::ContRef cont_;
475 public:
476 ConsPairFoldSRCont_cdr( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc )
477 : Kernel::Continuation( traceLoc ), car_( car ), op_( op ), opHandle_( opHandle ), nullResult_( nullResult ), state_( state ), dyn_( dyn ), cont_( cont )
479 virtual ~ConsPairFoldSRCont_cdr( ) { }
480 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
482 evalState->dyn_ = dyn_;
483 evalState->cont_ = Kernel::ContRef( new Kernel::ForceFunctionAndCall_2_args_1_state_cont( opHandle_, nullResult_, state_, dyn_,
484 Kernel::ContRef( new Kernel::SingleFoldSRCont( car_, op_, state_, evalState->dyn_, cont_, traceLoc_ ) ),
485 traceLoc_ ) );
486 Kernel::VariableHandle fun = val->getField( "foldsr", val );
487 fun->force( fun, evalState );
489 virtual Kernel::ContRef up( ) const
491 return cont_;
493 virtual RefCountPtr< const char > description( ) const
495 return strrefdup( "cons pair's foldl (force cdr)" );
497 virtual void gcMark( Kernel::GCMarkedSet & marked )
499 car_->gcMark( marked );
500 opHandle_->gcMark( marked ); /* This will gcMark op_ as well! */
501 nullResult_->gcMark( marked );
502 state_->gcMark( marked );
503 dyn_->gcMark( marked );
504 cont_->gcMark( marked );
512 Lang::SingleListPair::SingleListPair( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::SingleList > & cdr )
513 : car_( car ), cdr_( cdr ), forced_( cdr_->isForced( ) && ! car->isThunk( ) )
516 Lang::SingleListPair::~SingleListPair( )
519 void
520 Lang::SingleListPair::show( std::ostream & os ) const
522 os << "< non-empty singly linked list >" ;
525 bool
526 Lang::SingleListPair::isNull( ) const
528 return false;
531 bool
532 Lang::SingleListPair::isForced( ) const
534 return forced_;
537 void
538 Lang::SingleListPair::foldl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
540 evalState->cont_ = Kernel::ContRef( new Kernel::SingleFoldLCont( cdr_, op, evalState->dyn_, evalState->cont_, callLoc ) );
542 op->call( op, evalState, nullResult, car_, callLoc );
545 void
546 Lang::SingleListPair::foldr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
548 evalState->cont_ = Kernel::ContRef( new Kernel::SingleFoldRCont( car_, op, evalState->dyn_, evalState->cont_, callLoc ) );
550 cdr_->foldr( evalState, op, nullResult, callLoc );
553 void
554 Lang::SingleListPair::foldsl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
556 evalState->cont_ = Kernel::ContRef( new Kernel::SingleFoldSLCont( cdr_, op, state, evalState->dyn_, evalState->cont_, callLoc ) );
558 op->call( op, evalState, nullResult, car_, state, callLoc );
561 void
562 Lang::SingleListPair::foldsr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
564 evalState->cont_ = Kernel::ContRef( new Kernel::SingleFoldSRCont( car_, op, state, evalState->dyn_, evalState->cont_, callLoc ) );
566 cdr_->foldsr( evalState, op, nullResult, state, callLoc );
569 void
570 Lang::SingleListPair::gcMark( Kernel::GCMarkedSet & marked )
572 car_->gcMark( marked );
573 const_cast< Lang::SingleList * >( cdr_.getPtr( ) )->gcMark( marked );
576 Kernel::VariableHandle
577 Lang::SingleListPair::getField( const char * fieldId, const RefCountPtr< const Lang::Value > & selfRef ) const
579 if( strcmp( fieldId, "car" ) == 0 )
581 return car_;
583 if( strcmp( fieldId, "cdr" ) == 0 )
585 return Kernel::VariableHandle( new Kernel::Variable( cdr_ ) );
588 return SingleList::getField( fieldId, selfRef ); /* This will throw if there is no such method. */
591 Lang::SingleListNull::SingleListNull( )
594 Lang::SingleListNull::~SingleListNull( )
597 void
598 Lang::SingleListNull::show( std::ostream & os ) const
600 os << "< empty singly linked list >" ;
603 bool
604 Lang::SingleListNull::isNull( ) const
606 return true;
609 bool
610 Lang::SingleListNull::isForced( ) const
612 return true;
615 RefCountPtr< const Lang::Class > Lang::SingleListNull::TypeID( new Lang::SystemFinalClass( strrefdup( "SeqNil" ), SingleList_register_methods ) );
616 TYPEINFOIMPL( SingleListNull );
618 Kernel::VariableHandle
619 Lang::SingleListNull::getField( const char * fieldId, const RefCountPtr< const Lang::Value > & selfRef ) const
621 return TypeID->getMethod( selfRef, fieldId ); /* This will throw if there is no such method. */
624 void
625 Lang::SingleListNull::foldl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
627 Kernel::ContRef cont = evalState->cont_;
628 cont->takeHandle( nullResult,
629 evalState );
632 void
633 Lang::SingleListNull::foldr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
635 Kernel::ContRef cont = evalState->cont_;
636 cont->takeHandle( nullResult,
637 evalState );
640 void
641 Lang::SingleListNull::foldsl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
643 Kernel::ContRef cont = evalState->cont_;
644 cont->takeHandle( nullResult,
645 evalState );
648 void
649 Lang::SingleListNull::foldsr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
651 Kernel::ContRef cont = evalState->cont_;
652 cont->takeHandle( nullResult,
653 evalState );
657 Lang::ConsPair::ConsPair( const Kernel::VariableHandle & car, const Kernel::VariableHandle & cdr )
658 : car_( car ), cdr_( cdr )
661 Lang::ConsPair::~ConsPair( )
665 void
666 ConsPair_register_methods( Lang::SystemFinalClass * dstClass )
668 dstClass->registerMethod( new Kernel::MethodFactory< Lang::ConsPair, Lang::Method_foldl< Lang::ConsPair > >( ) );
669 dstClass->registerMethod( new Kernel::MethodFactory< Lang::ConsPair, Lang::Method_foldr< Lang::ConsPair > >( ) );
670 dstClass->registerMethod( new Kernel::MethodFactory< Lang::ConsPair, Lang::Method_foldsl< Lang::ConsPair > >( ) );
671 dstClass->registerMethod( new Kernel::MethodFactory< Lang::ConsPair, Lang::Method_foldsr< Lang::ConsPair > >( ) );
674 RefCountPtr< const Lang::Class > Lang::ConsPair::TypeID( new Lang::SystemFinalClass( strrefdup( "ConsPair" ), ConsPair_register_methods ) );
675 TYPEINFOIMPL( ConsPair );
677 void
678 Lang::ConsPair::show( std::ostream & os ) const
680 os << "< a lazy pair >" ;
683 Kernel::VariableHandle
684 Lang::ConsPair::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
686 if( strcmp( fieldID, "car" ) == 0 )
688 return car_;
690 if( strcmp( fieldID, "cdr" ) == 0 )
692 return cdr_;
695 return TypeID->getMethod( selfRef, fieldID ); /* This will throw if there is no such method. */
698 void
699 Lang::ConsPair::gcMark( Kernel::GCMarkedSet & marked )
701 car_->gcMark( marked );
702 cdr_->gcMark( marked );
705 void
706 Lang::ConsPair::foldl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
708 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldLCont_op( cdr_, opHandle, evalState->dyn_, evalState->cont_, callLoc ) );
710 op->call( op, evalState, nullResult, car_, callLoc );
713 void
714 Lang::ConsPair::foldr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
716 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldRCont_cdr( car_, op, opHandle, nullResult, evalState->dyn_, evalState->cont_, callLoc ) );
718 cdr_->force( cdr_, evalState );
721 void
722 Lang::ConsPair::foldsl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
724 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldSLCont_op( cdr_, opHandle, state, evalState->dyn_, evalState->cont_, callLoc ) );
726 op->call( op, evalState, nullResult, car_, state, callLoc );
729 void
730 Lang::ConsPair::foldsr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const
732 evalState->cont_ = Kernel::ContRef( new Kernel::ConsPairFoldSRCont_cdr( car_, op, opHandle, nullResult, state, evalState->dyn_, evalState->cont_, callLoc ) );
734 cdr_->force( cdr_, evalState );
738 template< class T >
739 Lang::Method_foldl< T >::Method_foldl( RefCountPtr< const T > self, const Ast::FileID * fullMethodID )
740 : Lang::MethodBase< T >( self, fullMethodID, false )
742 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE, true );
743 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "zero", Kernel::THE_SLOT_VARIABLE, false );
746 template< class T >
747 Lang::Method_foldl< T >::~Method_foldl( )
750 template< class T >
751 void
752 Lang::Method_foldl< T >::call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
754 args.applyDefaults( callLoc );
756 Lang::MethodBase< T >::self_->foldl( evalState,
757 Helpers::down_cast_CoreArgument< const Lang::Function >( Lang::MethodBase< T >::coreLoc_, args, 0, callLoc ),
758 args.getHandle( 0 ),
759 args.getHandle( 1 ),
760 callLoc );
764 template< class T >
765 Lang::Method_foldr< T >::Method_foldr( RefCountPtr< const T > self, const Ast::FileID * fullMethodID )
766 : Lang::MethodBase< T >( self, fullMethodID, false )
768 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE, true );
769 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "zero", Kernel::THE_SLOT_VARIABLE, false );
772 template< class T >
773 Lang::Method_foldr< T >::~Method_foldr( )
776 template< class T >
777 void
778 Lang::Method_foldr< T >::call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
780 args.applyDefaults( callLoc );
782 Lang::MethodBase< T >::self_->foldr( evalState,
783 Helpers::down_cast_CoreArgument< const Lang::Function >( Lang::MethodBase< T >::coreLoc_, args, 0, callLoc ),
784 args.getHandle( 0 ),
785 args.getHandle( 1 ),
786 callLoc );
790 template< class T >
791 Lang::Method_foldsl< T >::Method_foldsl( RefCountPtr< const T > self, const Ast::FileID * fullMethodID )
792 : Lang::MethodBase< T >( self, fullMethodID, false )
794 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE, true );
795 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "zero", Kernel::THE_SLOT_VARIABLE, false );
796 Lang::MethodBase< T >::formals_->appendCoreStateFormal( "state" );
799 template< class T >
800 Lang::Method_foldsl< T >::~Method_foldsl( )
803 template< class T >
804 void
805 Lang::Method_foldsl< T >::call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
807 args.applyDefaults( callLoc );
809 Lang::MethodBase< T >::self_->foldsl( evalState,
810 Helpers::down_cast_CoreArgument< const Lang::Function >( Lang::MethodBase< T >::coreLoc_, args, 0, callLoc ),
811 args.getHandle( 0 ),
812 args.getHandle( 1 ),
813 args.getState( 0 ),
814 callLoc );
818 template< class T >
819 Lang::Method_foldsr< T >::Method_foldsr( RefCountPtr< const T > self, const Ast::FileID * fullMethodID )
820 : Lang::MethodBase< T >( self, fullMethodID, false )
822 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE, true );
823 Lang::MethodBase< T >::formals_->appendEvaluatedCoreFormal( "zero", Kernel::THE_SLOT_VARIABLE, false );
824 Lang::MethodBase< T >::formals_->appendCoreStateFormal( "state" );
827 template< class T >
828 Lang::Method_foldsr< T >::~Method_foldsr( )
831 template< class T >
832 void
833 Lang::Method_foldsr< T >::call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const
835 args.applyDefaults( callLoc );
837 Lang::MethodBase< T >::self_->foldsr( evalState,
838 Helpers::down_cast_CoreArgument< const Lang::Function >( Lang::MethodBase< T >::coreLoc_, args, 0, callLoc ),
839 args.getHandle( 0 ),
840 args.getHandle( 1 ),
841 args.getState( 0 ),
842 callLoc );
846 Lang::Structure::Structure( const Ast::ArgListExprs * argList, const RefCountPtr< const Lang::SingleList > & values, bool argListOwner )
847 : argListOwner_( argListOwner ), argList_( argList ), values_( values )
850 Lang::Structure::~Structure( )
852 if( argListOwner_ )
854 delete argList_;
858 RefCountPtr< const Lang::Class > Lang::Structure::TypeID( new Lang::SystemFinalClass( strrefdup( "Union" ) ) );
859 TYPEINFOIMPL( Structure );
861 Kernel::VariableHandle
862 Lang::Structure::getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const
864 return argList_->findNamed( values_, fieldID );
867 size_t
868 Lang::Structure::valueCount( ) const
870 return argList_->orderedExprs_->size( ) + argList_->namedExprs_->size( );
873 Kernel::VariableHandle
874 Lang::Structure::getPosition( size_t pos, const RefCountPtr< const Lang::Value > & selfRef ) const
876 return argList_->getOrdered( values_, pos );
879 RefCountPtr< const Lang::Structure >
880 Lang::Structure::getSink( size_t consumedArguments ) const
882 if( argList_->orderedExprs_->size( ) <= consumedArguments )
884 return Lang::THE_EMPTY_STRUCT;
887 static std::vector< const Ast::ArgListExprs * > argLists;
888 size_t resSize = argList_->orderedExprs_->size( ) - consumedArguments;
889 if( resSize >= argLists.size( ) )
891 argLists.reserve( resSize + 1 );
892 while( argLists.size( ) <= resSize )
894 argLists.push_back( new Ast::ArgListExprs( argLists.size( ) ) );
898 RefCountPtr< const Lang::SingleList > resValues = values_;
901 for( size_t i = 0; i < consumedArguments; ++i )
903 resValues = Helpers::try_cast_CoreArgument< const Lang::SingleListPair >( resValues )->cdr_;
906 catch( const NonLocalExit::NotThisType & ball )
908 throw Exceptions::InternalError( "When constructing the sink, there was not enough arguments." );
910 return RefCountPtr< const Lang::Structure >( new Lang::Structure( argLists[ resSize ], resValues, false ) );
913 void
914 Lang::Structure::gcMark( Kernel::GCMarkedSet & marked )
916 const_cast< Lang::SingleList * >( values_.getPtr( ) )->gcMark( marked );
920 Kernel::StructureFactory::StructureFactory( const std::list< const char * > & fields )
922 init( fields );
925 Kernel::StructureFactory::StructureFactory( const char * field1 )
927 std::list< const char * > fields;
928 fields.push_back( field1 );
929 init( fields );
932 Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2 )
934 std::list< const char * > fields;
935 fields.push_back( field1 );
936 fields.push_back( field2 );
937 init( fields );
940 Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2, const char * field3 )
942 std::list< const char * > fields;
943 fields.push_back( field1 );
944 fields.push_back( field2 );
945 fields.push_back( field3 );
946 init( fields );
949 Kernel::StructureFactory::StructureFactory( const char * field1, const char * field2, const char * field3, const char * field4 )
951 std::list< const char * > fields;
952 fields.push_back( field1 );
953 fields.push_back( field2 );
954 fields.push_back( field3 );
955 fields.push_back( field4 );
956 init( fields );
959 void
960 Kernel::StructureFactory::init( const std::list< const char * > & fields )
962 Ast::ArgListExprs * tmp = new Ast::ArgListExprs( false );
963 typedef typeof fields ListType;
964 for( ListType::const_iterator i = fields.begin( ); i != fields.end( ); ++i )
966 (*tmp->namedExprs_)[ *i ] = 0;
967 typedef typeof values_ MapType;
968 values_.insert( MapType::value_type( *i, Kernel::THE_VOID_VARIABLE ) );
970 argList_ = tmp;
973 void
974 Kernel::StructureFactory::clear( )
976 typedef typeof values_ MapType;
977 for( MapType::iterator i = values_.begin( ); i != values_.end( ); ++i )
979 i->second = Kernel::THE_VOID_VARIABLE;
983 void
984 Kernel::StructureFactory::set( const char * field, const Kernel::VariableHandle & value )
986 typedef typeof values_ MapType;
987 MapType::iterator i = values_.find( field );
988 if( i == values_.end( ) )
990 throw Exceptions::InternalError( "Kernel::StructureFactory::set: Field was not declared." );
992 i->second = value;
995 RefCountPtr< const Lang::Structure >
996 Kernel::StructureFactory::build( )
998 RefCountPtr< const Lang::SingleList > tmp = Lang::THE_CONS_NULL;
999 typedef typeof values_ MapType;
1000 for( MapType::iterator i = values_.begin( ); i != values_.end( ); ++i )
1002 tmp = RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( i->second, tmp ) );
1004 return RefCountPtr< const Lang::Structure >( new Lang::Structure( argList_, tmp ) );
1008 Kernel::UnnamedStructureFactory::UnnamedStructureFactory( )
1011 RefCountPtr< const Lang::Structure >
1012 Kernel::UnnamedStructureFactory::build( const RefCountPtr< const Lang::SingleList > & values ) const
1014 /* Here we use that argLists_ is mutable, so that we can extend it with more entries as needed. */
1015 size_t sz = 0;
1016 for( RefCountPtr< const Lang::SingleList > tmp = values; ! tmp->isNull( ); tmp = dynamic_cast< const Lang::SingleListPair * >( tmp.getPtr( ) )->cdr_, ++sz )
1018 typedef typeof argLists_ MapType;
1019 MapType::iterator i = argLists_.find( sz );
1020 const Ast::ArgListExprs * argList = 0;
1021 if( i == argLists_.end( ) )
1023 Ast::ArgListExprs * tmp = new Ast::ArgListExprs( false );
1024 for( size_t i = 0; i < sz; ++i )
1026 tmp->orderedExprs_->push_back( 0 );
1028 argList = tmp;
1029 argLists_.insert( MapType::value_type( sz, argList ) );
1031 else
1033 argList = i->second;
1035 return RefCountPtr< const Lang::Structure >( new Lang::Structure( argList, values ) );
1039 Kernel::ForceFunctionAndCall_2_args_1_state_cont::ForceFunctionAndCall_2_args_1_state_cont( const Kernel::VariableHandle & arg1, const Kernel::VariableHandle & arg2, Kernel::StateHandle state, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc )
1040 : Kernel::Continuation( callLoc ), arg1_( arg1 ), arg2_( arg2 ), state_( state ), dyn_( dyn ), cont_( cont )
1043 Kernel::ForceFunctionAndCall_2_args_1_state_cont::~ForceFunctionAndCall_2_args_1_state_cont( )
1046 void
1047 Kernel::ForceFunctionAndCall_2_args_1_state_cont::takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const
1049 evalState->dyn_ = dyn_;
1050 evalState->cont_ = cont_;
1051 typedef const Lang::Function ArgType;
1052 RefCountPtr< ArgType > fun( Helpers::down_cast_ContinuationArgument< ArgType >( val, this ) );
1053 fun->call( fun, evalState, arg1_, arg2_, state_, traceLoc_ );
1056 Kernel::ContRef
1057 Kernel::ForceFunctionAndCall_2_args_1_state_cont::up( ) const
1059 return cont_;
1062 RefCountPtr< const char >
1063 Kernel::ForceFunctionAndCall_2_args_1_state_cont::description( ) const
1065 return strrefdup( "call function with two values and one state" );
1068 void
1069 Kernel::ForceFunctionAndCall_2_args_1_state_cont::gcMark( Kernel::GCMarkedSet & marked )
1071 arg1_->gcMark( marked );
1072 arg2_->gcMark( marked );
1073 dyn_->gcMark( marked );
1074 cont_->gcMark( marked );
1078 void
1079 Kernel::VectorFunction_register_methods( Lang::SystemFinalClass * dstClass )
1081 dstClass->registerMethod( new Kernel::MethodFactory< Lang::VectorFunction, Lang::Method_foldl< Lang::VectorFunction > >( ) );
1082 dstClass->registerMethod( new Kernel::MethodFactory< Lang::VectorFunction, Lang::Method_foldr< Lang::VectorFunction > >( ) );
1083 dstClass->registerMethod( new Kernel::MethodFactory< Lang::VectorFunction, Lang::Method_foldsl< Lang::VectorFunction > >( ) );
1084 dstClass->registerMethod( new Kernel::MethodFactory< Lang::VectorFunction, Lang::Method_foldsr< Lang::VectorFunction > >( ) );
1088 RefCountPtr< const Lang::SingleList >
1089 Helpers::SingleList_cons( Lang::Value * car, const RefCountPtr< const Lang::SingleList > & cdr )
1091 return RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( Kernel::ValueRef( car ) ) ),
1092 cdr ) );
1095 RefCountPtr< const Lang::SingleList >
1096 Helpers::SingleList_cons( const RefCountPtr< const Lang::Value > & car, const RefCountPtr< const Lang::SingleList > & cdr )
1098 return RefCountPtr< const Lang::SingleList >( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( car ) ),
1099 cdr ) );