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 Henrik Tidefelt
19 #include "shapestypes.h"
20 #include "shapesexceptions.h"
23 #include "angleselect.h"
28 using namespace Shapes
;
31 Lang::SingleList::SingleList( )
34 Lang::SingleList::~SingleList( )
37 RefCountPtr
< const Lang::Class
> Lang::SingleList::TypeID( new Lang::SystemFinalClass( strrefdup( "SingleList" ) ) );
38 TYPEINFOIMPL( SingleList
);
40 Kernel::VariableHandle
41 Lang::SingleList::getField( const char * fieldId
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
43 RefCountPtr
< const Lang::SingleList
> typedSelfRef
= Helpers::down_cast
< const Lang::SingleList
>( selfRef
, "< SingleList::getField >" );
44 if( strcmp( fieldId
, "foldl" ) == 0 )
46 return Helpers::newValHandle( new Lang::SingleListMethodFoldL( typedSelfRef
) );
48 if( strcmp( fieldId
, "foldr" ) == 0 )
50 return Helpers::newValHandle( new Lang::SingleListMethodFoldR( typedSelfRef
) );
52 if( strcmp( fieldId
, "foldsl" ) == 0 )
54 return Helpers::newValHandle( new Lang::SingleListMethodFoldSL( typedSelfRef
) );
56 if( strcmp( fieldId
, "foldsr" ) == 0 )
58 return Helpers::newValHandle( new Lang::SingleListMethodFoldSR( typedSelfRef
) );
60 throw Exceptions::NonExistentMember( getTypeName( ), fieldId
);
69 class SingleFoldLCont
: public Kernel::Continuation
71 RefCountPtr
< const Lang::SingleList
> cdr_
;
72 RefCountPtr
< const Lang::Function
> op_
;
73 Kernel::PassedDyn dyn_
;
74 Kernel::ContRef cont_
;
76 SingleFoldLCont( const RefCountPtr
< const Lang::SingleList
> & cdr
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
77 : Kernel::Continuation( traceLoc
), cdr_( cdr
), op_( op
), dyn_( dyn
), cont_( cont
)
79 virtual ~SingleFoldLCont( ) { }
80 virtual void takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
82 evalState
->dyn_
= dyn_
;
83 evalState
->cont_
= cont_
;
84 cdr_
->foldl( evalState
, op_
, val
, traceLoc_
);
86 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
88 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "singly linked list's foldl" ) );
89 cont_
->backTrace( trace
);
91 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
93 const_cast< Lang::SingleList
* >( cdr_
.getPtr( ) )->gcMark( marked
);
94 const_cast< Lang::Function
* >( op_
.getPtr( ) )->gcMark( marked
);
95 dyn_
->gcMark( marked
);
96 cont_
->gcMark( marked
);
100 class SingleFoldRCont
: public Kernel::Continuation
102 Kernel::VariableHandle car_
;
103 RefCountPtr
< const Lang::Function
> op_
;
104 Kernel::PassedDyn dyn_
;
105 Kernel::ContRef cont_
;
107 SingleFoldRCont( const Kernel::VariableHandle
& car
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::PassedDyn
& dyn
, Kernel::ContRef cont
, const Ast::SourceLocation
& traceLoc
)
108 : Kernel::Continuation( traceLoc
), car_( car
), op_( op
), dyn_( dyn
), cont_( cont
)
110 virtual ~SingleFoldRCont( ) { }
111 virtual void takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
113 evalState
->dyn_
= dyn_
;
114 evalState
->cont_
= cont_
;
115 op_
->call( op_
, evalState
, val
, car_
, traceLoc_
);
117 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
119 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "singly linked list's foldr" ) );
120 cont_
->backTrace( trace
);
122 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
124 car_
->gcMark( marked
);
125 const_cast< Lang::Function
* >( op_
.getPtr( ) )->gcMark( marked
);
126 dyn_
->gcMark( marked
);
127 cont_
->gcMark( marked
);
131 class SingleFoldSLCont
: public Kernel::Continuation
133 RefCountPtr
< const Lang::SingleList
> cdr_
;
134 RefCountPtr
< const Lang::Function
> op_
;
135 Kernel::StateHandle state_
;
136 Kernel::PassedDyn dyn_
;
137 Kernel::ContRef cont_
;
139 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
)
140 : Kernel::Continuation( traceLoc
), cdr_( cdr
), op_( op
), state_( state
), dyn_( dyn
), cont_( cont
)
142 virtual ~SingleFoldSLCont( ) { }
143 virtual void takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
145 evalState
->dyn_
= dyn_
;
146 evalState
->cont_
= cont_
;
147 cdr_
->foldsl( evalState
, op_
, val
, state_
, traceLoc_
);
149 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
151 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "singly linked list's foldsl" ) );
152 cont_
->backTrace( trace
);
154 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
156 const_cast< Lang::SingleList
* >( cdr_
.getPtr( ) )->gcMark( marked
);
157 const_cast< Lang::Function
* >( op_
.getPtr( ) )->gcMark( marked
);
158 state_
->gcMark( marked
);
159 dyn_
->gcMark( marked
);
160 cont_
->gcMark( marked
);
164 class SingleFoldSRCont
: public Kernel::Continuation
166 Kernel::VariableHandle car_
;
167 RefCountPtr
< const Lang::Function
> op_
;
168 Kernel::StateHandle state_
;
169 Kernel::PassedDyn dyn_
;
170 Kernel::ContRef cont_
;
172 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
)
173 : Kernel::Continuation( traceLoc
), car_( car
), op_( op
), state_( state
),dyn_( dyn
), cont_( cont
)
175 virtual ~SingleFoldSRCont( ) { }
176 virtual void takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
178 evalState
->dyn_
= dyn_
;
179 evalState
->cont_
= cont_
;
180 op_
->call( op_
, evalState
, val
, car_
, state_
, traceLoc_
);
182 virtual void backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
184 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "singly linked list's foldsr" ) );
185 cont_
->backTrace( trace
);
187 virtual void gcMark( Kernel::GCMarkedSet
& marked
)
189 car_
->gcMark( marked
);
190 const_cast< Lang::Function
* >( op_
.getPtr( ) )->gcMark( marked
);
191 state_
->gcMark( marked
);
192 dyn_
->gcMark( marked
);
193 cont_
->gcMark( marked
);
201 Lang::SingleListPair::SingleListPair( const Kernel::VariableHandle
& car
, const RefCountPtr
< const Lang::SingleList
> & cdr
)
202 : car_( car
), cdr_( cdr
)
205 Lang::SingleListPair::~SingleListPair( )
209 Lang::SingleListPair::isNull( ) const
215 Lang::SingleListPair::foldl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
217 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldLCont( cdr_
, op
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
219 op
->call( op
, evalState
, nullResult
, car_
, callLoc
);
223 Lang::SingleListPair::foldr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
225 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldRCont( car_
, op
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
227 cdr_
->foldr( evalState
, op
, nullResult
, callLoc
);
231 Lang::SingleListPair::foldsl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
233 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldSLCont( cdr_
, op
, state
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
235 op
->call( op
, evalState
, nullResult
, car_
, state
, callLoc
);
239 Lang::SingleListPair::foldsr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
241 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldSRCont( car_
, op
, state
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
243 cdr_
->foldsr( evalState
, op
, nullResult
, state
, callLoc
);
247 Lang::SingleListPair::gcMark( Kernel::GCMarkedSet
& marked
)
249 car_
->gcMark( marked
);
250 const_cast< Lang::SingleList
* >( cdr_
.getPtr( ) )->gcMark( marked
);
253 Lang::SingleListNull::SingleListNull( )
256 Lang::SingleListNull::~SingleListNull( )
260 Lang::SingleListNull::isNull( ) const
266 Lang::SingleListNull::foldl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
268 Kernel::ContRef cont
= evalState
->cont_
;
269 cont
->takeHandle( nullResult
,
274 Lang::SingleListNull::foldr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
276 Kernel::ContRef cont
= evalState
->cont_
;
277 cont
->takeHandle( nullResult
,
282 Lang::SingleListNull::foldsl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
284 Kernel::ContRef cont
= evalState
->cont_
;
285 cont
->takeHandle( nullResult
,
290 Lang::SingleListNull::foldsr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
292 Kernel::ContRef cont
= evalState
->cont_
;
293 cont
->takeHandle( nullResult
,
298 Lang::ConsPair::ConsPair( const Kernel::VariableHandle
& car
, const Kernel::VariableHandle
& cdr
)
299 : car_( car
), cdr_( cdr
)
302 Lang::ConsPair::~ConsPair( )
305 RefCountPtr
< const Lang::Class
> Lang::ConsPair::TypeID( new Lang::SystemFinalClass( strrefdup( "ConsPair" ) ) );
306 TYPEINFOIMPL( ConsPair
);
309 Lang::ConsPair::show( std::ostream
& os
) const
311 os
<< "< a lazy pair >" ;
314 Kernel::VariableHandle
315 Lang::ConsPair::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
317 if( strcmp( fieldID
, "car" ) == 0 )
321 if( strcmp( fieldID
, "cdr" ) == 0 )
325 throw Exceptions::NonExistentMember( getTypeName( ), fieldID
);
329 Lang::ConsPair::gcMark( Kernel::GCMarkedSet
& marked
)
331 car_
->gcMark( marked
);
332 cdr_
->gcMark( marked
);
336 Lang::SingleListMethodBase::SingleListMethodBase( RefCountPtr
< const Lang::SingleList
> self
, Kernel::EvaluatedFormals
* formals
)
337 : Lang::Function( formals
), self_( self
)
340 Lang::SingleListMethodBase::~SingleListMethodBase( )
344 Lang::SingleListMethodBase::gcMark( Kernel::GCMarkedSet
& marked
)
346 const_cast< Lang::SingleList
* >( self_
.getPtr( ) )->gcMark( marked
);
350 Lang::SingleListMethodBase::isTransforming( ) const
355 Lang::SingleListMethodFoldL::SingleListMethodFoldL( RefCountPtr
< const Lang::SingleList
> self
)
356 : Lang::SingleListMethodBase( self
,
357 new Kernel::EvaluatedFormals( strdup( Kernel::MethodId( Lang::SingleList::TypeID
, "foldl" ).prettyName( ).getPtr( ) ) ) )
359 formals_
->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE
, true );
360 formals_
->appendEvaluatedCoreFormal( "nullRes", Kernel::THE_SLOT_VARIABLE
, false );
363 Lang::SingleListMethodFoldL::~SingleListMethodFoldL( )
367 Lang::SingleListMethodFoldL::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
369 args
.applyDefaults( );
371 self_
->foldl( evalState
,
372 Helpers::down_cast_CoreArgument
< const Lang::Function
>( "< core method foldl >", args
, 0, callLoc
),
377 Lang::SingleListMethodFoldR::SingleListMethodFoldR( RefCountPtr
< const Lang::SingleList
> self
)
378 : Lang::SingleListMethodBase( self
,
379 new Kernel::EvaluatedFormals( strdup( Kernel::MethodId( Lang::SingleList::TypeID
, "foldr" ).prettyName( ).getPtr( ) ) ) )
381 formals_
->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE
, true );
382 formals_
->appendEvaluatedCoreFormal( "nullRes", Kernel::THE_SLOT_VARIABLE
, false );
385 Lang::SingleListMethodFoldR::~SingleListMethodFoldR( )
389 Lang::SingleListMethodFoldR::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
391 args
.applyDefaults( );
393 self_
->foldr( evalState
,
394 Helpers::down_cast_CoreArgument
< const Lang::Function
>( "< core method foldr >", args
, 0, callLoc
),
399 Lang::SingleListMethodFoldSL::SingleListMethodFoldSL( RefCountPtr
< const Lang::SingleList
> self
)
400 : Lang::SingleListMethodBase( self
,
401 new Kernel::EvaluatedFormals( strdup( Kernel::MethodId( Lang::SingleList::TypeID
, "foldsl" ).prettyName( ).getPtr( ) ) ) )
403 formals_
->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE
, true );
404 formals_
->appendEvaluatedCoreFormal( "nullRes", Kernel::THE_SLOT_VARIABLE
, false );
405 formals_
->appendCoreStateFormal( "state" );
408 Lang::SingleListMethodFoldSL::~SingleListMethodFoldSL( )
412 Lang::SingleListMethodFoldSL::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
414 args
.applyDefaults( );
416 self_
->foldsl( evalState
,
417 Helpers::down_cast_CoreArgument
< const Lang::Function
>( "< core method foldl >", args
, 0, callLoc
),
423 Lang::SingleListMethodFoldSR::SingleListMethodFoldSR( RefCountPtr
< const Lang::SingleList
> self
)
424 : Lang::SingleListMethodBase( self
,
425 new Kernel::EvaluatedFormals( strdup( Kernel::MethodId( Lang::SingleList::TypeID
, "foldsr" ).prettyName( ).getPtr( ) ) ) )
427 formals_
->appendEvaluatedCoreFormal( "op", Kernel::THE_SLOT_VARIABLE
, true );
428 formals_
->appendEvaluatedCoreFormal( "nullRes", Kernel::THE_SLOT_VARIABLE
, false );
429 formals_
->appendCoreStateFormal( "state" );
432 Lang::SingleListMethodFoldSR::~SingleListMethodFoldSR( )
436 Lang::SingleListMethodFoldSR::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
438 args
.applyDefaults( );
440 self_
->foldsr( evalState
,
441 Helpers::down_cast_CoreArgument
< const Lang::Function
>( "< core method foldr >", args
, 0, callLoc
),
448 Lang::Structure::Structure( const Ast::ArgListExprs
* argList
, const RefCountPtr
< const Lang::SingleList
> & values
, bool argListOwner
)
449 : argListOwner_( argListOwner
), argList_( argList
), values_( values
)
452 Lang::Structure::~Structure( )
460 RefCountPtr
< const Lang::Class
> Lang::Structure::TypeID( new Lang::SystemFinalClass( strrefdup( "Union" ) ) );
461 TYPEINFOIMPL( Structure
);
463 Kernel::VariableHandle
464 Lang::Structure::getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
466 return argList_
->findNamed( values_
, fieldID
);
469 Kernel::VariableHandle
470 Lang::Structure::getPosition( size_t pos
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
472 return argList_
->getOrdered( values_
, pos
);
475 RefCountPtr
< const Lang::Structure
>
476 Lang::Structure::getSink( size_t consumedArguments
) const
478 if( argList_
->orderedExprs_
->size( ) <= consumedArguments
)
480 return Lang::THE_EMPTY_STRUCT
;
483 static std::vector
< const Ast::ArgListExprs
* > argLists
;
484 size_t resSize
= argList_
->orderedExprs_
->size( ) - consumedArguments
;
485 if( resSize
>= argLists
.size( ) )
487 argLists
.reserve( resSize
+ 1 );
488 while( argLists
.size( ) <= resSize
)
490 argLists
.push_back( new Ast::ArgListExprs( argLists
.size( ) ) );
494 RefCountPtr
< const Lang::SingleList
> resValues
= values_
;
497 for( size_t i
= 0; i
< consumedArguments
; ++i
)
499 resValues
= Helpers::try_cast_CoreArgument
< const Lang::SingleListPair
>( resValues
)->cdr_
;
502 catch( const NonLocalExit::NotThisType
& ball
)
504 throw Exceptions::InternalError( "When constructing the sink, there was not enough arguments." );
506 return RefCountPtr
< const Lang::Structure
>( new Lang::Structure( argLists
[ resSize
], resValues
, false ) );
510 Lang::Structure::gcMark( Kernel::GCMarkedSet
& marked
)
512 const_cast< Lang::SingleList
* >( values_
.getPtr( ) )->gcMark( marked
);
516 Kernel::StructureFactory::StructureFactory( const std::list
< const char * > & fields
)
521 Kernel::StructureFactory::StructureFactory( const char * field1
)
523 std::list
< const char * > fields
;
524 fields
.push_back( field1
);
528 Kernel::StructureFactory::StructureFactory( const char * field1
, const char * field2
)
530 std::list
< const char * > fields
;
531 fields
.push_back( field1
);
532 fields
.push_back( field2
);
536 Kernel::StructureFactory::StructureFactory( const char * field1
, const char * field2
, const char * field3
)
538 std::list
< const char * > fields
;
539 fields
.push_back( field1
);
540 fields
.push_back( field2
);
541 fields
.push_back( field3
);
545 Kernel::StructureFactory::StructureFactory( const char * field1
, const char * field2
, const char * field3
, const char * field4
)
547 std::list
< const char * > fields
;
548 fields
.push_back( field1
);
549 fields
.push_back( field2
);
550 fields
.push_back( field3
);
551 fields
.push_back( field4
);
556 Kernel::StructureFactory::init( const std::list
< const char * > & fields
)
558 Ast::ArgListExprs
* tmp
= new Ast::ArgListExprs( false );
559 typedef typeof fields ListType
;
560 for( ListType::const_iterator i
= fields
.begin( ); i
!= fields
.end( ); ++i
)
562 (*tmp
->namedExprs_
)[ *i
] = 0;
563 typedef typeof values_ MapType
;
564 values_
.insert( MapType::value_type( *i
, Kernel::THE_VOID_VARIABLE
) );
570 Kernel::StructureFactory::clear( )
572 typedef typeof values_ MapType
;
573 for( MapType::iterator i
= values_
.begin( ); i
!= values_
.end( ); ++i
)
575 i
->second
= Kernel::THE_VOID_VARIABLE
;
580 Kernel::StructureFactory::set( const char * field
, const Kernel::VariableHandle
& value
)
582 typedef typeof values_ MapType
;
583 MapType::iterator i
= values_
.find( field
);
584 if( i
== values_
.end( ) )
586 throw Exceptions::InternalError( "Kernel::StructureFactory::set: Field was not declared." );
591 RefCountPtr
< const Lang::Structure
>
592 Kernel::StructureFactory::build( )
594 RefCountPtr
< const Lang::SingleList
> tmp
= Lang::THE_CONS_NULL
;
595 typedef typeof values_ MapType
;
596 for( MapType::iterator i
= values_
.begin( ); i
!= values_
.end( ); ++i
)
598 tmp
= RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListPair( i
->second
, tmp
) );
600 return RefCountPtr
< const Lang::Structure
>( new Lang::Structure( argList_
, tmp
) );