Update procedures
[shapes.git] / source / functiontypes.h
blob21148556ddafebc13e8b2286e42ef4ff257dfc88
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, 2014 Henrik Tidefelt
19 #pragma once
21 #include "Shapes_Lang_decls.h"
22 #include "Shapes_Kernel_decls.h"
23 #include "Shapes_Ast_decls.h"
25 #include "shapesvalue.h"
26 #include "ptrowner.h"
27 #include "refcount.h"
28 #include "pdfstructure.h"
29 #include "environment.h"
30 #include "charptrless.h"
31 #include "consts.h"
32 #include "elementarytypes.h"
33 #include "elementarycoords.h"
35 #include <list>
36 #include <iostream>
37 #include <stack>
38 #include <set>
39 #include <gsl/gsl_matrix.h>
42 #define CHECK_ARITY( argsVar, arity, idExpr ) \
43 if( argsVar.size( ) != ARITY )\
45 throw Exceptions::CoreArityMismatch( idExpr, arity, argsVar.size( ) );\
50 namespace Shapes
53 namespace Kernel
56 class Arguments
58 const Kernel::EvaluatedFormals * formals_;
59 Environment::ValueVector variables_;
60 std::vector< const Ast::Node * > locations_;
61 size_t dst_;
62 bool hasSink_;
63 // Putting dstEnd_ after hasSink_ makes initialization more convenient.
64 size_t dstEnd_; // This is one less than there are variables if there is a sink.
65 bool isSink_; // This is used by functions in the core.
67 Ast::ArgListExprs * sinkArgList_; // If null, there is no sink.
68 RefCountPtr< const Lang::SingleList > sinkValues_;
70 Environment::StateVector states_; // This type must match that used in Environment
71 std::vector< const Ast::Node * > stateLocations_;
72 size_t stateDst_;
74 Kernel::StateHandle mutatorSelf_;
76 public:
77 Arguments( const Kernel::EvaluatedFormals * formals );
78 ~Arguments( );
80 Kernel::Arguments clone( ) const;
82 void addOrderedArgument( const Kernel::VariableHandle & arg, Ast::Expression * loc );
83 void addNamedArgument( const char * id, const Kernel::VariableHandle & arg, Ast::Expression * loc );
85 void addOrderedState( const Kernel::StateHandle & state, Ast::Node * loc );
86 void addNamedState( const char * id, const Kernel::StateHandle & state, Ast::Node * loc );
88 void applyDefaults( const Ast::SourceLocation & callLoc );
90 Kernel::VariableHandle & getHandle( size_t i );
91 RefCountPtr< const Lang::Value > & getValue( size_t i );
92 const Ast::SourceLocation & getLoc( size_t i ) const;
93 const Ast::Node * getNode( size_t i ) const;
94 Kernel::Thunk * getThunk( size_t i ); // This funciton returns a newly created copy!
95 bool isSlot( size_t i ) const;
97 size_t size( ) const;
98 bool empty( ) const;
100 Kernel::StateHandle getState( size_t i );
101 const Ast::SourceLocation & getStateLoc( size_t i ) const;
103 void setMutatorSelf( Kernel::StateHandle mutatorSelf );
104 Kernel::StateHandle getMutatorSelf( );
106 void gcMark( Kernel::GCMarkedSet & marked );
108 Environment::ValueVector getVariables( ); // This function should only be called when setting up a new environment
109 Environment::StateVector getStates( ); // This function should only be called when setting up a new environment
112 class EvaluatedFormals
114 bool selectiveForcing_;
115 bool forceAll_;
116 public:
117 Kernel::Formals * formals_; /* it would have been const if it was not for appendEvaluatedFormal */
118 std::vector< Kernel::VariableHandle > defaults_;
119 std::vector< const Ast::Node * > locations_;
120 bool isSink_;
122 EvaluatedFormals( Kernel::Formals * _formals );
123 EvaluatedFormals( const Ast::FileID * locationFileID );
124 EvaluatedFormals( const Ast::FileID * locationFileID, bool _forceAll );
125 ~EvaluatedFormals( );
127 void appendEvaluatedFormal( const char * id, const Kernel::VariableHandle & defaultVal, const Ast::Node * loc, bool force );
128 void appendEvaluatedFormal( const char * id, const Kernel::VariableHandle & defaultVal, const Ast::Node * loc );
129 void appendEvaluatedCoreFormal( const char * id, const Kernel::VariableHandle & defaultVal, bool force );
130 void appendEvaluatedCoreFormal( const char * id, const Kernel::VariableHandle & defaultVal );
131 void appendCoreStateFormal( const char * id );
133 RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState ) const;
134 RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, const Kernel::Arguments & curryArgs ) const;
136 void gcMark( Kernel::GCMarkedSet & marked );
139 void VectorFunction_register_methods( Lang::SystemFinalClass * dstClass ); /* Implemented in containertypes.cc for convenience. */
143 namespace Helpers
146 template< class T >
147 RefCountPtr< T >
148 down_cast_CoreArgument( const Ast::PlacedIdentifier & calleeId, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc, bool voidIsNull = false )
150 RefCountPtr< const Lang::Value > val = args.getValue( i );
151 RefCountPtr< T > res = val.down_cast< T >( );
152 if( res == NullPtr< T >( ) )
154 if( ! voidIsNull ||
155 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
157 throw Exceptions::CoreTypeMismatch( callLoc, calleeId, args, i, T::staticTypeName( ) );
160 return res;
163 template< class T >
164 RefCountPtr< T >
165 down_cast_CoreArgument( const RefCountPtr< const Interaction::CoreLocation > coreLoc, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc, bool voidIsNull = false )
167 RefCountPtr< const Lang::Value > val = args.getValue( i );
168 RefCountPtr< T > res = val.down_cast< T >( );
169 if( res == NullPtr< T >( ) )
171 if( ! voidIsNull ||
172 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
174 throw Exceptions::CoreTypeMismatch( callLoc, coreLoc, args, i, T::staticTypeName( ) );
177 return res;
180 template< class T >
181 RefCountPtr< T >
182 down_cast_SyntaxArgument( const char * syntax, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc, bool voidIsNull = false )
184 RefCountPtr< const Lang::Value > val = args.getValue( i );
185 RefCountPtr< T > res = val.down_cast< T >( );
186 if( res == NullPtr< T >( ) )
188 if( ! voidIsNull ||
189 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
191 throw Exceptions::CoreTypeMismatch( callLoc, new Interaction::CharPtrLocation( syntax ), args.getLoc( i ), val->getTypeName( ), T::staticTypeName( ) );
194 return res;
197 template< class T >
198 RefCountPtr< T >
199 down_cast_MutatorArgument( const Kernel::State * state, const char * name, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc, bool voidIsNull = false )
201 RefCountPtr< const Lang::Value > val = args.getValue( i );
202 RefCountPtr< T > res = val.down_cast< T >( );
203 if( res == NullPtr< T >( ) )
205 if( ! voidIsNull ||
206 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
208 throw Exceptions::CoreTypeMismatch( callLoc, new Interaction::MutatorLocation( state, name ), args, i, T::staticTypeName( ) );
211 return res;
214 template< class T >
215 RefCountPtr< T >
216 down_cast_StructureContinuationArgument( const char * continuationName, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc, bool voidIsNull = false )
218 RefCountPtr< const Lang::Value > val = args.getValue( i );
219 RefCountPtr< T > res = val.down_cast< T >( );
220 if( res == NullPtr< T >( ) )
222 if( ! voidIsNull ||
223 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
225 throw Exceptions::CoreTypeMismatch( callLoc, new Interaction::CharPtrLocation( continuationName ), args, i, T::staticTypeName( ) );
228 return res;
231 template< class T >
233 down_cast_CoreState( const Ast::PlacedIdentifier & calleeId, Kernel::Arguments & args, size_t i, const Ast::SourceLocation & callLoc )
235 Kernel::StateHandle st = args.getState( i );
236 T * res = dynamic_cast< T * >( st );
237 if( res == NullPtr< T >( ) )
239 throw Exceptions::CoreStateTypeMismatch( callLoc, calleeId, args.getStateLoc( i ), st->getTypeName( ), T::staticTypeName( ) );
241 return res;
244 template< class T >
245 RefCountPtr< T >
246 down_cast_CoreDynamic( const Ast::PlacedIdentifier & calleeId, const Ast::PlacedIdentifier & id, const RefCountPtr< const Lang::Value > & val, const Ast::SourceLocation & callLoc )
248 RefCountPtr< T > res = val.down_cast< T >( );
249 if( res == NullPtr< T >( ) )
251 throw Exceptions::CoreDynamicTypeMismatch( callLoc, calleeId, id, val->getTypeName( ), T::staticTypeName( ) );
253 return res;
256 template< class T >
257 RefCountPtr< T >
258 try_cast_CoreArgument( const RefCountPtr< const Lang::Value > & val, bool voidIsNull = false )
260 RefCountPtr< T > res = val.down_cast< T >( );
261 if( res == NullPtr< T >( ) )
263 if( ! voidIsNull ||
264 dynamic_cast< const Lang::Void * >( val.getPtr( ) ) == 0 )
266 throw NonLocalExit::NotThisType( );
269 return res;
272 template< class T >
274 try_cast_CoreState( Kernel::StateHandle st )
276 T * res = dynamic_cast< T * >( st );
277 if( res == NullPtr< T >( ) )
279 throw NonLocalExit::NotThisType( );
281 return res;
284 template< class T >
286 mutator_cast_self( Kernel::StateHandle st )
288 T * res = dynamic_cast< T * >( st );
289 if( res == NullPtr< T >( ) )
291 throw Exceptions::InternalError( "Type of self state does not match mutator signature." );
293 return res;
299 namespace Lang
302 class Transform2D : public Lang::Value
304 public:
305 double xx_;
306 double yx_;
307 double xy_;
308 double yy_;
309 Concrete::Length xt_;
310 Concrete::Length yt_;
311 Transform2D( double xx, double yx, double xy, double yy,
312 Concrete::Length xt, Concrete::Length yt );
313 Transform2D( const Lang::Transform2D & tf2, const Lang::Transform2D & tf1 );
314 virtual ~Transform2D( );
315 virtual Kernel::VariableHandle getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const;
316 Transform2D * clone( ) const;
317 bool isIdentity( ) const;
318 bool isTranslation( ) const;
319 void write_gsl_matrix( gsl_matrix * matrix_2_2 ) const;
320 void write_gsl_vector( gsl_vector * vec_2 ) const;
321 void shipout( std::ostream & os ) const;
322 void replaceBy( const Lang::Transform2D & newtf ); // to be used by text moveto commands
323 void prependShift( const Concrete::Coords2D & d ); // to be used by text newline commands
324 void prependXShift( const Concrete::Length & dx ); // to be used by text painting commands
325 void prependYShift( const Concrete::Length & dy ); // to be used for text rise
326 void prependXScale( double a ); // to be used for text horizontal scaling
327 TYPEINFODECL;
328 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
329 virtual void show( std::ostream & os ) const;
330 DISPATCHDECL;
333 class Transform3D : public Lang::Value
335 static const int N = 3;
336 mutable gsl_matrix * planeNormalTransformData_;
337 public:
338 double xx_;
339 double yx_;
340 double zx_;
341 double xy_;
342 double yy_;
343 double zy_;
344 double xz_;
345 double yz_;
346 double zz_;
347 Concrete::Length xt_;
348 Concrete::Length yt_;
349 Concrete::Length zt_;
350 Transform3D( double xx, double yx, double zx, double xy, double yy, double zy, double xz, double yz, double zz,
351 Concrete::Length xt, Concrete::Length yt, Concrete::Length zt );
352 Transform3D( const gsl_matrix * matrix_3_3, const gsl_vector * vec_3 );
353 Transform3D( const Lang::Transform3D & tf2, const Lang::Transform3D & tf1 );
354 virtual ~Transform3D( );
355 virtual Kernel::VariableHandle getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const;
356 Transform3D * clone( ) const;
357 bool isIdentity( ) const;
358 bool isTranslation( ) const;
359 Concrete::UnitFloatTriple transformPlaneUnitNormal( const Concrete::UnitFloatTriple & n ) const;
360 void write_gsl_matrix( gsl_matrix * matrix_3_3 ) const;
361 void write_gsl_vector( gsl_vector * vec_3 ) const;
362 TYPEINFODECL;
363 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
364 virtual void show( std::ostream & os ) const;
365 DISPATCHDECL;
368 class Function : public Lang::Value
370 protected:
371 Kernel::EvaluatedFormals * formals_; /* the reason that this is not const is only to allow convenient setup */
372 virtual void analyze_impl( Ast::Node * parent, Ast::AnalysisEnvironment * env, Ast::StateIDSet * freeStatesDst );
373 public:
374 Function( Kernel::EvaluatedFormals * formals );
375 virtual ~Function( );
376 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const = 0;
377 virtual Kernel::ValueRef transformed( const Lang::Transform2D & tf, Kernel::ValueRef self ) const;
378 virtual bool isTransforming( ) const = 0;
379 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState ) const;
380 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, const Kernel::Arguments & curryArgs ) const;
381 virtual Kernel::Arguments newCurriedArguments( ) const;
382 virtual void call( Kernel::EvalState * evalState, const Kernel::ValueRef & arg1, const Ast::SourceLocation & callLoc ) const;
383 virtual void call( Kernel::EvalState * evalState, const Kernel::ValueRef & arg1, const Kernel::ValueRef & arg2, const Ast::SourceLocation & callLoc ) const;
384 virtual void call( const RefCountPtr< const Lang::Function > & selfRef, Kernel::EvalState * evalState, const Kernel::VariableHandle & arg1, const Ast::SourceLocation & callLoc ) const;
385 virtual void call( const RefCountPtr< const Lang::Function > & selfRef, Kernel::EvalState * evalState, const Kernel::VariableHandle & arg1, const Kernel::VariableHandle & arg2, const Ast::SourceLocation & callLoc ) const;
386 virtual void call( const RefCountPtr< const Lang::Function > & selfRef, Kernel::EvalState * evalState, const Kernel::VariableHandle & arg1, const Kernel::VariableHandle & arg2, Kernel::StateHandle state, const Ast::SourceLocation & callLoc ) const;
388 void analyze( Ast::Node * parent, Ast::AnalysisEnvironment * env );
390 TYPEINFODECL;
391 DISPATCHDECL;
392 private:
393 static Ast::ArgListExprs * oneExprArgList;
394 static Ast::ArgListExprs * twoExprsArgList;
397 class CuteFunction : public Lang::Function
399 RefCountPtr< const Lang::Function > callee_;
400 Kernel::Arguments someArgs_;
401 public:
402 CuteFunction( RefCountPtr< const Lang::Function > _callee, const Kernel::Arguments & _someArgs );
403 virtual ~CuteFunction( );
404 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState ) const;
405 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, const Kernel::Arguments & curryArgs ) const;
406 virtual Kernel::Arguments newCurriedArguments( ) const;
407 virtual void gcMark( Kernel::GCMarkedSet & marked );
408 virtual void show( std::ostream & os ) const;
409 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
410 virtual bool isTransforming( ) const;
413 class ComposedFunction : public Lang::Function
415 RefCountPtr< const Lang::Function > second_;
416 RefCountPtr< const Lang::Function > first_;
417 public:
418 ComposedFunction( const RefCountPtr< const Lang::Function > & _second, const RefCountPtr< const Lang::Function > & _first );
419 virtual ~ComposedFunction( );
420 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState ) const;
421 virtual RefCountPtr< Kernel::CallContInfo > newCallContInfo( const Ast::ArgListExprs * argList, const Kernel::EvalState & evalState, const Kernel::Arguments & curryArgs ) const;
422 virtual Kernel::Arguments newCurriedArguments( ) const;
423 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
424 virtual bool isTransforming( ) const;
425 virtual void gcMark( Kernel::GCMarkedSet & marked );
426 virtual void show( std::ostream & os ) const;
429 class Span : public Lang::Function
431 RefCountPtr< const Kernel::SpanThunks > thunks_;
432 public:
433 Span( const Kernel::VariableHandle & begin, const Kernel::VariableHandle & end, const Kernel::VariableHandle & step, const Kernel::VariableHandle & count );
434 virtual ~Span( );
435 virtual void gcMark( Kernel::GCMarkedSet & marked );
436 virtual void show( std::ostream & os ) const;
437 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
438 virtual bool isTransforming( ) const;
439 static const RefCountPtr< const Interaction::CoreLocation > coreLoc;
440 TYPEINFODECL;
443 class UserFunction : public Lang::Function
445 Ast::Expression * body_;
446 Kernel::PassedEnv env_;
447 Ast::FunctionMode functionMode_;
448 public:
449 UserFunction( Kernel::EvaluatedFormals * _formals, Ast::Expression * _body, Kernel::PassedEnv _env, const Ast::FunctionMode & _functionMode );
450 virtual ~UserFunction( );
451 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
452 virtual bool isTransforming( ) const;
453 virtual void show( std::ostream & os ) const;
454 virtual void gcMark( Kernel::GCMarkedSet & marked );
455 Ast::Expression * body( ); /* Will typically require a const_cast to be callable. */
458 class TransformedFunction2D : public Lang::Function
460 Lang::Transform2D tf_;
461 RefCountPtr< const Lang::Function > fun_;
462 public:
463 TransformedFunction2D( const Lang::Transform2D & _tf, const RefCountPtr< const Lang::Function > & _fun );
464 virtual ~TransformedFunction2D( );
465 virtual void gcMark( Kernel::GCMarkedSet & marked );
466 virtual void show( std::ostream & os ) const;
467 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
468 virtual bool isTransforming( ) const;
471 class VectorFunction : public Lang::Function
473 public:
474 typedef std::vector< Kernel::ValueRef > vector_type;
475 private:
476 RefCountPtr< const vector_type > mem_;
477 mutable RefCountPtr< const std::vector< double > > memNumeric_;
478 mutable Kernel::VariableHandle list_;
479 static const RefCountPtr< const Interaction::CoreLocation > coreLoc;
480 public:
481 VectorFunction( const std::vector< Kernel::ValueRef > * mem );
482 virtual ~VectorFunction( );
483 virtual Kernel::VariableHandle getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const;
484 virtual void gcMark( Kernel::GCMarkedSet & marked );
485 static void gcMark( const RefCountPtr< const std::vector< Kernel::ValueRef > > & mem, Kernel::GCMarkedSet & marked );
486 virtual void show( std::ostream & os ) const;
487 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
488 virtual bool isTransforming( ) const;
489 RefCountPtr< const vector_type > mem( ) const { return mem_; }
490 RefCountPtr< const std::vector< double > > getNumeric( const Ast::SourceLocation & callLoc ) const;
492 static void foldl( const RefCountPtr< const std::vector< Kernel::ValueRef > > & mem, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, vector_type::const_iterator i, const Ast::SourceLocation & callLoc );
493 static void foldr( const RefCountPtr< const std::vector< Kernel::ValueRef > > & mem, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, vector_type::const_reverse_iterator i, const Ast::SourceLocation & callLoc );
494 static void foldsl( const RefCountPtr< const std::vector< Kernel::ValueRef > > & mem, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, vector_type::const_iterator i, const Ast::SourceLocation & callLoc );
495 static void foldsr( const RefCountPtr< const std::vector< Kernel::ValueRef > > & mem, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & nullResult, Kernel::StateHandle state, vector_type::const_reverse_iterator i, const Ast::SourceLocation & callLoc );
497 /* In order to be able to use the same method template as ConsPair, we support that the <op> argument is additionally passed as a VariableHandle. */
498 inline void foldl( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
500 foldl( mem_, evalState, op, nullResult, mem_->begin( ), callLoc );
502 inline void foldr( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Function > & op, const Kernel::VariableHandle & opHandle, const Kernel::VariableHandle & nullResult, const Ast::SourceLocation & callLoc ) const
504 foldr( mem_, evalState, op, nullResult, mem_->rbegin( ), callLoc );
506 inline void 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
508 foldsl( mem_, evalState, op, nullResult, state, mem_->begin( ), callLoc );
510 inline void 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
512 foldsr( mem_, evalState, op, nullResult, state, mem_->rbegin( ), callLoc );
515 TYPEINFODECL;
516 private:
517 void compute_list( ) const; /* This will modify mutable data! */
520 class ColorInterpolator : public Lang::Function
522 public:
523 typedef std::vector< double > KeyContainer;
524 typedef std::vector< Concrete::RGB > RGBContainer;
525 typedef std::vector< Concrete::Gray > GrayContainer;
526 typedef std::vector< Concrete::CMYK > CMYKContainer;
527 enum ColorType { UNDEFINED, RGB, GRAY, CMYK };
529 private:
530 RefCountPtr< const KeyContainer > key_;
531 RefCountPtr< const RGBContainer > RGBcolor_;
532 RefCountPtr< const GrayContainer > graycolor_;
533 RefCountPtr< const CMYKContainer > CMYKcolor_;
534 ColorType colorType_;
535 static const char * title;
536 static const RefCountPtr< const Interaction::CoreLocation > coreLoc;
538 public:
539 ColorInterpolator( const RefCountPtr< KeyContainer > & key,
540 const RefCountPtr< RGBContainer > & RGBcolor,
541 const RefCountPtr< GrayContainer > & graycolor,
542 const RefCountPtr< CMYKContainer > & CMYKcolor,
543 ColorType colorType );
544 virtual ~ColorInterpolator( );
545 virtual Kernel::VariableHandle getField( const char * fieldID, const RefCountPtr< const Lang::Value > & selfRef ) const;
546 virtual void gcMark( Kernel::GCMarkedSet & marked );
547 virtual void show( std::ostream & os ) const;
548 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
549 virtual bool isTransforming( ) const;
551 private:
552 template< class COLOR_TYPE, class COLOR_CONTAINER >
553 void callHelper( Kernel::EvalState * evalState, const RefCountPtr< COLOR_CONTAINER > & colorContainer,
554 double key, KeyContainer::const_iterator keyHi ) const;
558 class BinaryOperatorFunction : public Lang::Function
560 Ast::BinaryInfixExpr * opExpr_;
561 RefCountPtr< const Interaction::CoreLocation > coreLoc_;
562 public:
563 BinaryOperatorFunction( Ast::BinaryInfixExpr * opExpr, const char * coreSyntax );
564 virtual ~BinaryOperatorFunction( );
565 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
566 virtual bool isTransforming( ) const;
567 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
568 virtual void show( std::ostream & os ) const;
571 class UnaryOperatorFunction : public Lang::Function
573 Ast::UnaryExpr * opExpr_;
574 RefCountPtr< const Interaction::CoreLocation > coreLoc_;
575 public:
576 UnaryOperatorFunction( Ast::UnaryExpr * opExpr, const char * coreSyntax );
577 virtual ~UnaryOperatorFunction( );
578 virtual void call( Kernel::EvalState * evalState, Kernel::Arguments & args, const Ast::SourceLocation & callLoc ) const;
579 virtual bool isTransforming( ) const;
580 virtual void gcMark( Kernel::GCMarkedSet & marked ){ };
581 virtual void show( std::ostream & os ) const;