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 2010, 2013 Henrik Tidefelt
19 #include "containertypes.h"
20 #include "shapesexceptions.h"
21 #include "continuations.h"
24 /* This file is divided in two parts. The first part contains the declarations.
32 class SingleListRange
: public Lang::SingleList
34 typedef typename
T::ValueType elem_type
;
39 SingleListRange( elem_type begin
, elem_type step
, size_t count
);
40 virtual ~SingleListRange( );
41 virtual void show( std::ostream
& os
) const;
42 virtual bool isNull( ) const;
43 virtual bool isForced( ) const;
44 virtual void foldl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const;
45 virtual void foldr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const;
46 virtual void foldsl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const;
47 virtual void foldsr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const;
48 virtual void gcMark( Kernel::GCMarkedSet
& marked
){ };
49 virtual Kernel::VariableHandle
getField( const char * fieldID
, const RefCountPtr
< const Lang::Value
> & selfRef
) const;
51 RefCountPtr
< const Lang::SingleListPair
> consify( ) const;
52 void expand( std::vector
< elem_type
> * dst
) const;
59 /* This is the start of the second part of the file, containing the implementation of the templates declared in the first part.
65 Lang::SingleListRange
< T
>::SingleListRange( elem_type begin
, elem_type step
, size_t count
)
66 : begin_( begin
), step_( step
), count_( count
)
69 throw Exceptions::InternalError( "Attempt to construct SingleListRange with zero count." );
73 Lang::SingleListRange
< T
>::~SingleListRange( )
78 Lang::SingleListRange
< T
>::show( std::ostream
& os
) const
80 os
<< "< range with " << count_
<< " elements >" ;
85 Lang::SingleListRange
< T
>::isNull( ) const
92 Lang::SingleListRange
< T
>::isForced( ) const
99 Lang::SingleListRange
< T
>::foldl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
102 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldLCont( RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListRange
< T
>( begin_
+ step_
, step_
, count_
- 1 ) ),
103 op
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
106 op
->call( op
, evalState
, nullResult
, Helpers::newValHandle( new T( begin_
) ), callLoc
);
111 Lang::SingleListRange
< T
>::foldr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, const Ast::SourceLocation
& callLoc
) const
113 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldRCont( Helpers::newValHandle( new T( begin_
) ), op
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
116 Lang::SingleListRange
< T
>( begin_
+ step_
, step_
, count_
- 1 ).foldr( evalState
, op
, nullResult
, callLoc
);
118 Kernel::ContRef cont
= evalState
->cont_
;
119 cont
->takeHandle( nullResult
,
126 Lang::SingleListRange
< T
>::foldsl( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
129 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldSLCont( RefCountPtr
< const Lang::SingleList
>( new Lang::SingleListRange
< T
>( begin_
+ step_
, step_
, count_
- 1 ) ),
130 op
, state
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
133 op
->call( op
, evalState
, nullResult
, Helpers::newValHandle( new T( begin_
) ), state
, callLoc
);
138 Lang::SingleListRange
< T
>::foldsr( Kernel::EvalState
* evalState
, const RefCountPtr
< const Lang::Function
> & op
, const Kernel::VariableHandle
& nullResult
, Kernel::StateHandle state
, const Ast::SourceLocation
& callLoc
) const
140 evalState
->cont_
= Kernel::ContRef( new Kernel::SingleFoldSRCont( Helpers::newValHandle( new T( begin_
) ), op
, state
, evalState
->dyn_
, evalState
->cont_
, callLoc
) );
143 Lang::SingleListRange
< T
>( begin_
+ step_
, step_
, count_
- 1 ).foldsr( evalState
, op
, nullResult
, state
, callLoc
);
145 Kernel::ContRef cont
= evalState
->cont_
;
146 cont
->takeHandle( nullResult
,
152 Kernel::VariableHandle
153 Lang::SingleListRange
< T
>::getField( const char * fieldId
, const RefCountPtr
< const Lang::Value
> & selfRef
) const
155 if( strcmp( fieldId
, "car" ) == 0 )
157 return Helpers::newValHandle( new T( begin_
) );
159 if( strcmp( fieldId
, "cdr" ) == 0 )
162 return Kernel::VariableHandle( new Kernel::Variable( Lang::THE_CONS_NULL
) );
164 return Helpers::newValHandle( new SingleListRange
< T
>( begin_
+ step_
, step_
, count_
- 1 ) );
167 return SingleList::getField( fieldId
, selfRef
); /* This will throw if there is no such method. */
171 RefCountPtr
< const Lang::SingleListPair
>
172 Lang::SingleListRange
< T
>::consify( ) const
174 std::vector
< elem_type
> mem
;
175 mem
.reserve( count_
);
177 elem_type i
= begin_
;
185 RefCountPtr
< const Lang::SingleListPair
> result
=
186 RefCountPtr
< const Lang::SingleListPair
>
187 ( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( Kernel::ValueRef( new T( mem
.back( ) ) ) ) ),
188 Lang::THE_CONS_NULL
) );
190 while( ! mem
.empty( ) ){
192 RefCountPtr
< const Lang::SingleListPair
>
193 ( new Lang::SingleListPair( Kernel::VariableHandle( new Kernel::Variable( Kernel::ValueRef( new T( mem
.back( ) ) ) ) ),
203 Lang::SingleListRange
< T
>::expand( std::vector
< elem_type
> * dst
) const
205 dst
->reserve( dst
->size( ) + count_
);
207 elem_type i
= begin_
;