Update procedures
[shapes.git] / source / continuations.h
blob64e86283e5aad18e2e5333e4e537c1be85cb728e
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, 2013, 2014 Henrik Tidefelt
19 #pragma once
21 #include "ast.h"
23 namespace Shapes
25 namespace Helpers
28 template< class T >
29 RefCountPtr< T >
30 down_cast_ContinuationArgument( const RefCountPtr< const Lang::Value > & val, const Kernel::Continuation * locCont, bool voidIsNull = false )
32 RefCountPtr< T > res = val.down_cast< T >( );
33 if( res == NullPtr< T >( ) )
35 if( ! voidIsNull ||
36 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
38 throw Exceptions::ContinuationTypeMismatch( locCont, val->getTypeName( ), T::staticTypeName( ) );
41 return res;
46 namespace Kernel
49 class ExitContinuation : public Kernel::Continuation
51 bool * done_;
52 public:
53 ExitContinuation( bool * done, const Ast::SourceLocation & traceLoc );
54 ~ExitContinuation( );
55 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
56 virtual Kernel::ContRef up( ) const;
57 virtual RefCountPtr< const char > description( ) const;
58 virtual void gcMark( Kernel::GCMarkedSet & marked );
61 class DefaultErrorContinuation : public Kernel::Continuation
63 public:
64 DefaultErrorContinuation( const Ast::SourceLocation & traceLoc );
65 ~DefaultErrorContinuation( );
66 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
67 virtual Kernel::ContRef up( ) const;
68 virtual RefCountPtr< const char > description( ) const;
69 virtual void gcMark( Kernel::GCMarkedSet & marked );
72 class IfContinuation : public Kernel::Continuation
74 Kernel::VariableHandle consequence_;
75 Kernel::VariableHandle alternative_;
76 Kernel::ContRef cont_;
77 public:
78 IfContinuation( const Kernel::VariableHandle & consequence, const Kernel::VariableHandle & alternative, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
79 ~IfContinuation( );
80 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
81 virtual Kernel::ContRef up( ) const;
82 virtual RefCountPtr< const char > description( ) const;
83 virtual void gcMark( Kernel::GCMarkedSet & marked );
86 /* IgnoreContinuation is used by when forcing thunks for immediate right hand sides of bind nodes.
88 class IgnoreContinuation : public Kernel::Continuation
90 Kernel::ContRef cont_;
91 public:
92 IgnoreContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
93 ~IgnoreContinuation( );
94 virtual void takeHandle( Kernel::VariableHandle 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 );
100 /* IntroduceStateContinuation is used by the expression IntroduceState.
102 class IntroduceStateContinuation : public Kernel::Continuation
104 Kernel::PassedEnv env_;
105 size_t * pos_;
106 Kernel::ContRef cont_;
107 public:
108 IntroduceStateContinuation( const Kernel::PassedEnv & _env, size_t * _pos, const Kernel::ContRef & _cont, const Ast::SourceLocation & _traceLoc );
109 ~IntroduceStateContinuation( );
110 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
111 virtual Kernel::ContRef up( ) const;
112 virtual RefCountPtr< const char > description( ) const;
113 virtual void gcMark( Kernel::GCMarkedSet & marked );
116 /* StoreValueContinuation will store the returned object at the specified address, and then pass it on
117 * to the next continuation.
118 * Note that it is the responsibility of someone else to make sure that *res still exists when the continuation is invoked.
119 * Generally, StoreVariableContinuation shall be preferred since it has no such problem.
121 class StoreValueContinuation : public Kernel::Continuation
123 Kernel::ValueRef * res_;
124 Kernel::ContRef cont_;
125 public:
126 StoreValueContinuation( Kernel::ValueRef * res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
127 ~StoreValueContinuation( );
128 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
129 virtual Kernel::ContRef up( ) const;
130 virtual RefCountPtr< const char > description( ) const;
131 virtual void gcMark( Kernel::GCMarkedSet & marked );
134 class StoreVariableContinuation : public Kernel::Continuation
136 Kernel::VariableHandle dst_;
137 Kernel::ContRef cont_;
138 public:
139 StoreVariableContinuation( const Kernel::VariableHandle & res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
140 ~StoreVariableContinuation( );
141 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
142 virtual Kernel::ContRef up( ) const;
143 virtual RefCountPtr< const char > description( ) const;
144 virtual void gcMark( Kernel::GCMarkedSet & marked );
147 /* The InsertionContinuation sends the returned value to a warm variable, and passes THE_SLOT_VARIABLE (a null value) to the next continuation.
149 class InsertionContinuation : public Kernel::Continuation
151 mutable Kernel::StateHandle dst_; /* This being mutable is actually quite ugly... */
152 Kernel::PassedDyn dyn_;
153 Kernel::ContRef cont_;
154 public:
155 InsertionContinuation( const Kernel::StateHandle & dst, const Kernel::ContRef & cont, const Kernel::PassedDyn & dyn, const Ast::SourceLocation & traceLoc );
156 ~InsertionContinuation( );
157 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
158 virtual Kernel::ContRef up( ) const;
159 virtual RefCountPtr< const char > description( ) const;
160 virtual void gcMark( Kernel::GCMarkedSet & marked );
163 /* StmtStoreValueContinuation is like StoreValueContinuation, except that it passes THE_SLOT_VARIABLE (a null value) to the next continuation.
165 class StmtStoreValueContinuation : public Kernel::Continuation
167 Kernel::ValueRef * res_;
168 Kernel::ContRef cont_;
169 public:
170 StmtStoreValueContinuation( Kernel::ValueRef * res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
171 ~StmtStoreValueContinuation( );
172 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
173 virtual Kernel::ContRef up( ) const;
174 virtual RefCountPtr< const char > description( ) const;
175 virtual void gcMark( Kernel::GCMarkedSet & marked );
178 class StmtStoreVariableContinuation : public Kernel::Continuation
180 Kernel::VariableHandle dst_;
181 Kernel::ContRef cont_;
182 public:
183 StmtStoreVariableContinuation( const Kernel::VariableHandle & res, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
184 ~StmtStoreVariableContinuation( );
185 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
186 virtual Kernel::ContRef up( ) const;
187 virtual RefCountPtr< const char > description( ) const;
188 virtual void gcMark( Kernel::GCMarkedSet & marked );
191 class ForcingContinuation : public Kernel::Continuation
193 Kernel::ContRef cont_;
194 public:
195 ForcingContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
196 ~ForcingContinuation( );
197 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
198 virtual Kernel::ContRef up( ) const;
199 virtual RefCountPtr< const char > description( ) const;
200 virtual void gcMark( Kernel::GCMarkedSet & marked );
203 class ForcingListContinuation : public Kernel::Continuation
205 Kernel::ContRef cont_;
206 bool forceStructures_; /* Force any list element that is a Structure. */
207 bool consify_; /* Expand resulting list to only use the SingleListPair and SingleListNull subtypes of SingleList. */
208 size_t index_; /* Index of element being forced, initially 0. */
209 RefCountPtr< const Lang::SingleList > pile_; /* Accumulator for forced result. */
210 public:
211 ForcingListContinuation( const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc, bool forceStructures = false, bool consify = false );
212 ForcingListContinuation( bool forceStructures, bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
213 ~ForcingListContinuation( );
214 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
215 virtual Kernel::ContRef up( ) const;
216 virtual RefCountPtr< const char > description( ) const;
217 virtual void gcMark( Kernel::GCMarkedSet & marked );
220 class ForcingListCarContinuation : public Kernel::Continuation
222 Kernel::ContRef cont_;
223 bool forceStructures_; /* If forced value is Structure, force its fields. */
224 bool consify_; /* Expand resulting list to only use the SingleListPair and SingleListNull subtypes of SingleList. */
225 size_t index_; /* Index of element being forced, initially 0. */
226 RefCountPtr< const Lang::SingleList > cdr_;
227 RefCountPtr< const Lang::SingleList > pile_; /* Accumulator for forced result. */
228 public:
229 ForcingListCarContinuation( bool forceStructures, bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
230 ~ForcingListCarContinuation( );
231 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
232 virtual Kernel::ContRef up( ) const;
233 virtual RefCountPtr< const char > description( ) const;
234 virtual void gcMark( Kernel::GCMarkedSet & marked );
237 class ForcingListCarStructureContinuation : public Kernel::ForcedStructureContinuation
239 Kernel::ContRef cont_;
240 bool consify_; /* Expand resulting list to only use the SingleListPair and SingleListNull subtypes of SingleList. */
241 size_t index_; /* Index of element being forced, initially 0. */
242 RefCountPtr< const Lang::SingleList > cdr_;
243 RefCountPtr< const Lang::SingleList > pile_; /* Accumulator for forced result. */
244 public:
245 ForcingListCarStructureContinuation( bool consify, size_t index, const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
246 ~ForcingListCarStructureContinuation( );
247 virtual void takeStructure( const RefCountPtr< const Lang::Structure > & structure, Kernel::EvalState * evalState ) const;
248 virtual Kernel::ContRef up( ) const;
249 virtual RefCountPtr< const char > description( ) const;
250 virtual void gcMark( Kernel::GCMarkedSet & marked );
253 class ForcingConsCarContinuation : public Kernel::Continuation
255 Kernel::ContRef cont_;
256 bool forceStructures_; /* If forced value is Structure, force its fields. */
257 bool consify_; /* Expand resulting list to only use the SingleListPair and SingleListNull subtypes of SingleList. */
258 size_t index_; /* Index of element being forced, initially 0. */
259 Kernel::VariableHandle cdr_;
260 RefCountPtr< const Lang::SingleList > pile_; /* Accumulator for forced result. */
261 public:
262 ForcingConsCarContinuation( bool forceStructures, bool consify, size_t index, const Kernel::VariableHandle & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
263 ~ForcingConsCarContinuation( );
264 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
265 virtual Kernel::ContRef up( ) const;
266 virtual RefCountPtr< const char > description( ) const;
267 virtual void gcMark( Kernel::GCMarkedSet & marked );
270 class ForcingConsCarStructureContinuation : public Kernel::ForcedStructureContinuation
272 Kernel::ContRef cont_;
273 bool consify_; /* Expand resulting list to only use the SingleListPair and SingleListNull subtypes of SingleList. */
274 size_t index_; /* Index of element being forced, initially 0. */
275 Kernel::VariableHandle cdr_;
276 RefCountPtr< const Lang::SingleList > pile_; /* Accumulator for forced result. */
277 public:
278 ForcingConsCarStructureContinuation( bool consify, size_t index, const Kernel::VariableHandle & cdr, const RefCountPtr< const Lang::SingleList > & pile, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
279 ~ForcingConsCarStructureContinuation( );
280 virtual void takeStructure( const RefCountPtr< const Lang::Structure > & structure, Kernel::EvalState * evalState ) const;
281 virtual Kernel::ContRef up( ) const;
282 virtual RefCountPtr< const char > description( ) const;
283 virtual void gcMark( Kernel::GCMarkedSet & marked );
286 class Transform2DCont : public Kernel::Continuation
288 Lang::Transform2D tf_;
289 Kernel::ContRef cont_;
290 public:
291 Transform2DCont( Lang::Transform2D tf, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
292 virtual ~Transform2DCont( );
293 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
294 virtual Kernel::ContRef up( ) const;
295 virtual RefCountPtr< const char > description( ) const;
296 virtual void gcMark( Kernel::GCMarkedSet & marked );
299 class Transform3DCont : public Kernel::Continuation
301 Lang::Transform3D tf_;
302 Kernel::ContRef cont_;
303 public:
304 Transform3DCont( Lang::Transform3D tf, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
305 virtual ~Transform3DCont( );
306 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
307 virtual Kernel::ContRef up( ) const;
308 virtual RefCountPtr< const char > description( ) const;
309 virtual void gcMark( Kernel::GCMarkedSet & marked );
312 class PathApplication2DCont : public Kernel::Continuation
314 RefCountPtr< const Lang::ElementaryPath2D > path_;
315 Kernel::ContRef cont_;
316 public:
317 PathApplication2DCont( RefCountPtr< const Lang::ElementaryPath2D > path, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
318 virtual ~PathApplication2DCont( );
319 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
320 virtual Kernel::ContRef up( ) const;
321 virtual RefCountPtr< const char > description( ) const;
322 virtual void gcMark( Kernel::GCMarkedSet & marked );
325 class PathApplication3DCont : public Kernel::Continuation
327 RefCountPtr< const Lang::ElementaryPath3D > path_;
328 Kernel::ContRef cont_;
329 public:
330 PathApplication3DCont( RefCountPtr< const Lang::ElementaryPath3D > path, const Kernel::ContRef & cont, const Ast::SourceLocation & traceLoc );
331 virtual ~PathApplication3DCont( );
332 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
333 virtual Kernel::ContRef up( ) const;
334 virtual RefCountPtr< const char > description( ) const;
335 virtual void gcMark( Kernel::GCMarkedSet & marked );
338 class ComposedFunctionCall_cont : public Kernel::Continuation
340 RefCountPtr< const Lang::Function > second_;
341 Kernel::PassedDyn dyn_;
342 Kernel::ContRef cont_;
343 public:
344 ComposedFunctionCall_cont( const RefCountPtr< const Lang::Function > & second, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc );
345 virtual ~ComposedFunctionCall_cont( );
346 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
347 virtual Kernel::ContRef up( ) const;
348 virtual RefCountPtr< const char > description( ) const;
349 virtual void gcMark( Kernel::GCMarkedSet & marked );
352 class ForceFunctionAndCall_2_args_cont : public Kernel::Continuation
354 Kernel::VariableHandle arg1_;
355 Kernel::VariableHandle arg2_;
356 Kernel::PassedDyn dyn_;
357 Kernel::ContRef cont_;
358 public:
359 ForceFunctionAndCall_2_args_cont( const Kernel::VariableHandle & arg1, const Kernel::VariableHandle & arg2, const Kernel::PassedDyn & dyn, const Kernel::ContRef & cont, const Ast::SourceLocation & callLoc );
360 virtual ~ForceFunctionAndCall_2_args_cont( );
361 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
362 virtual Kernel::ContRef up( ) const;
363 virtual RefCountPtr< const char > description( ) const;
364 virtual void gcMark( Kernel::GCMarkedSet & marked );
367 class SingleFoldLCont : public Kernel::Continuation
369 RefCountPtr< const Lang::SingleList > cdr_;
370 RefCountPtr< const Lang::Function > op_;
371 Kernel::PassedDyn dyn_;
372 Kernel::ContRef cont_;
373 public:
374 SingleFoldLCont( const RefCountPtr< const Lang::SingleList > & cdr, const RefCountPtr< const Lang::Function > & op, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc );
375 virtual ~SingleFoldLCont( );
376 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
377 virtual Kernel::ContRef up( ) const;
378 virtual RefCountPtr< const char > description( ) const;
379 virtual void gcMark( Kernel::GCMarkedSet & marked );
382 class SingleFoldRCont : public Kernel::Continuation
384 Kernel::VariableHandle car_;
385 RefCountPtr< const Lang::Function > op_;
386 Kernel::PassedDyn dyn_;
387 Kernel::ContRef cont_;
388 public:
389 SingleFoldRCont( const Kernel::VariableHandle & car, const RefCountPtr< const Lang::Function > & op, const Kernel::PassedDyn & dyn, Kernel::ContRef cont, const Ast::SourceLocation & traceLoc );
390 virtual ~SingleFoldRCont( );
391 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
392 virtual Kernel::ContRef up( ) const;
393 virtual RefCountPtr< const char > description( ) const;
394 virtual void gcMark( Kernel::GCMarkedSet & marked );
397 class SingleFoldSLCont : public Kernel::Continuation
399 RefCountPtr< const Lang::SingleList > cdr_;
400 RefCountPtr< const Lang::Function > op_;
401 Kernel::StateHandle state_;
402 Kernel::PassedDyn dyn_;
403 Kernel::ContRef cont_;
404 public:
405 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 );
406 virtual ~SingleFoldSLCont( );
407 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
408 virtual Kernel::ContRef up( ) const;
409 virtual RefCountPtr< const char > description( ) const;
410 virtual void gcMark( Kernel::GCMarkedSet & marked );
413 class SingleFoldSRCont : public Kernel::Continuation
415 Kernel::VariableHandle car_;
416 RefCountPtr< const Lang::Function > op_;
417 Kernel::StateHandle state_;
418 Kernel::PassedDyn dyn_;
419 Kernel::ContRef cont_;
420 public:
421 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 );
422 virtual ~SingleFoldSRCont( );
423 virtual void takeHandle( Kernel::VariableHandle val, Kernel::EvalState * evalState, bool dummy ) const;
424 virtual Kernel::ContRef up( ) const;
425 virtual RefCountPtr< const char > description( ) const;
426 virtual void gcMark( Kernel::GCMarkedSet & marked );
429 class RelaxContinuation : public Kernel::Continuation
431 Kernel::ContRef cont_;
432 public:
433 RelaxContinuation( Kernel::ContRef & cont );
434 virtual ~RelaxContinuation( );
435 virtual void takeValue( const RefCountPtr< const Lang::Value > & val, Kernel::EvalState * evalState, bool dummy ) const;
436 virtual Kernel::ContRef up( ) const;
437 virtual RefCountPtr< const char > description( ) const;
438 virtual void gcMark( Kernel::GCMarkedSet & marked );