1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2010, 2013 Henrik Tidefelt
19 #include "shapestypes.h"
20 #include "shapesexceptions.h"
22 #include "continuations.h"
24 #include "angleselect.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
;
40 class Method_foldl
: public Lang::MethodBase
< T
>
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"; }
50 class Method_foldr
: public Lang::MethodBase
< T
>
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"; }
60 class Method_foldsl
: public Lang::MethodBase
< T
>
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"; }
70 class Method_foldsr
: public Lang::MethodBase
< T
>
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"; }
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_
;
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( )
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( )
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_
);
145 Kernel::SingleFoldLCont::up( ) const
150 RefCountPtr
< const char >
151 Kernel::SingleFoldLCont::description( ) const
153 return strrefdup( "singly linked list's foldl" );
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( )
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_
);
182 Kernel::SingleFoldRCont::up( ) const
187 RefCountPtr
< const char >
188 Kernel::SingleFoldRCont::description( ) const
190 return strrefdup( "foldr" );
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( )
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_
);
219 Kernel::SingleFoldSLCont::up( ) const
224 RefCountPtr
< const char >
225 Kernel::SingleFoldSLCont::description( ) const
227 return strrefdup( "singly linked list's foldsl" );
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( )
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_
);
257 Kernel::SingleFoldSRCont::up( ) const
262 RefCountPtr
< const char >
263 Kernel::SingleFoldSRCont::description( ) const
265 return strrefdup( "foldsr" );
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
);
284 class ConsPairFoldLCont_cdr
: public Kernel::Continuation
286 Kernel::VariableHandle op_
;
287 Kernel::VariableHandle nullResult_
;
288 Kernel::PassedDyn dyn_
;
289 Kernel::ContRef cont_
;
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
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_
;
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
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_
;
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_
) ),
372 Kernel::VariableHandle fun
= val
->getField( "foldr", val
);
373 fun
->force( fun
, evalState
);
375 virtual Kernel::ContRef
up( ) const
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_
;
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
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_
;
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
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_
;
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_
) ),
486 Kernel::VariableHandle fun
= val
->getField( "foldsr", val
);
487 fun
->force( fun
, evalState
);
489 virtual Kernel::ContRef
up( ) const
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( )
520 Lang::SingleListPair::show( std::ostream
& os
) const
522 os
<< "< non-empty singly linked list >" ;
526 Lang::SingleListPair::isNull( ) const
532 Lang::SingleListPair::isForced( ) const
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
);
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
);
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
);
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
);
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 )
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( )
598 Lang::SingleListNull::show( std::ostream
& os
) const
600 os
<< "< empty singly linked list >" ;
604 Lang::SingleListNull::isNull( ) const
610 Lang::SingleListNull::isForced( ) const
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. */
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
,
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
,
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
,
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
,
657 Lang::ConsPair::ConsPair( const Kernel::VariableHandle
& car
, const Kernel::VariableHandle
& cdr
)
658 : car_( car
), cdr_( cdr
)
661 Lang::ConsPair::~ConsPair( )
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
);
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 )
690 if( strcmp( fieldID
, "cdr" ) == 0 )
695 return TypeID
->getMethod( selfRef
, fieldID
); /* This will throw if there is no such method. */
699 Lang::ConsPair::gcMark( Kernel::GCMarkedSet
& marked
)
701 car_
->gcMark( marked
);
702 cdr_
->gcMark( marked
);
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
);
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
);
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
);
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
);
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 );
747 Lang::Method_foldl
< T
>::~Method_foldl( )
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
),
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 );
773 Lang::Method_foldr
< T
>::~Method_foldr( )
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
),
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" );
800 Lang::Method_foldsl
< T
>::~Method_foldsl( )
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
),
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" );
828 Lang::Method_foldsr
< T
>::~Method_foldsr( )
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
),
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( )
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
);
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 ) );
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
)
925 Kernel::StructureFactory::StructureFactory( const char * field1
)
927 std::list
< const char * > fields
;
928 fields
.push_back( field1
);
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
);
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
);
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
);
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
) );
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
;
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." );
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. */
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 );
1029 argLists_
.insert( MapType::value_type( sz
, argList
) );
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( )
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_
);
1057 Kernel::ForceFunctionAndCall_2_args_1_state_cont::up( ) const
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" );
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
);
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
) ) ),
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
) ),