2 #include "shapesexceptions.h"
5 #include "specialunits.h"
7 #include "continuations.h"
8 #include "containertypes.h"
10 using namespace Shapes
;
14 Ast::CodeBracket::CodeBracket( const Ast::SourceLocation
& loc
, std::list
< Ast::Node
* > * nodes
)
15 : Ast::Expression( loc
), nodes_( nodes
), argumentOrder_( new typeof *argumentOrder_
), dynamicMap_( 0 ), stateOrder_( new typeof *stateOrder_
)
17 for( std::list
< Ast::Node
* >::const_iterator i
= nodes_
->begin( );
21 typedef const Ast::BindNode T
;
22 T
* tmp
= dynamic_cast< T
* >( *i
);
25 const char * name
= tmp
->id( );
27 typedef const Ast::DefineVariable T
;
28 T
* decl
= dynamic_cast< T
* >( tmp
);
31 if( argumentOrder_
->find( name
) != argumentOrder_
->end( ) )
33 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
36 argumentOrder_
->insert( std::pair
< const char *, size_t >( name
, argumentOrder_
->size( ) ) );
41 typedef const Ast::IntroduceState T
;
42 T
* decl
= dynamic_cast< T
* >( tmp
);
45 if( stateOrder_
->find( name
) != stateOrder_
->end( ) )
47 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
50 stateOrder_
->insert( std::pair
< const char *, size_t >( name
, stateOrder_
->size( ) ) );
55 typedef const Ast::DynamicVariableDecl T
;
56 T
* dynDecl
= dynamic_cast< T
* >( tmp
);
59 if( dynamicMap_
== 0 )
61 dynamicMap_
= new std::map
< const char *, size_t, charPtrLess
>;
63 if( dynamicMap_
->find( name
) != dynamicMap_
->end( ) )
65 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
68 dynamicMap_
->insert( std::pair
< const char *, size_t >( name
, dynamicMap_
->size( ) ) );
76 Ast::CodeBracket::~CodeBracket( )
78 typedef list
< Ast::Node
* >::iterator I
;
79 for( I i
= nodes_
->begin( ); i
!= nodes_
->end( ); ++i
)
84 delete argumentOrder_
;
85 if( dynamicMap_
!= 0 )
94 Ast::CodeBracket::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* parentEnv
)
98 Ast::AnalysisEnvironment
* env( new Ast::AnalysisEnvironment( Ast::theAnalysisEnvironmentList
, parentEnv
, argumentOrder_
, stateOrder_
) );
99 if( dynamicMap_
!= 0 )
101 env
->setupDynamicKeyVariables( dynamicMap_
);
106 typedef list
< Ast::Node
* >::iterator I
;
107 for( I i
= nodes_
->begin( ); i
!= nodes_
->end( ); ++i
)
109 (*i
)->analyze( this, env
);
116 typedef list
< Ast::Node
* >::const_iterator I
;
117 for( I i
= nodes_
->begin( ); i
!= nodes_
->end( ); ++i
)
119 if( dynamic_cast< Ast::Expression
* >( *i
) != 0 &&
120 ! (*i
)->imperative_
)
124 if( tmp
!= nodes_
->end( ) )
126 Ast::theAnalysisErrorsList
.push_back( new Exceptions::ExpectedImperative( (*i
)->loc( ) ) );
129 imperative_
= imperative_
|| (*i
)->imperative_
;
135 Ast::CodeBracket::eval( Kernel::EvalState
* evalState
) const
137 if( nodes_
->begin( ) == nodes_
->end( ) )
139 Kernel::ContRef cont
= evalState
->cont_
;
140 cont
->takeValue( Lang::THE_VOID
,
145 std::vector
< Kernel::VariableHandle
> * envValues
= new std::vector
< Kernel::VariableHandle
>;
146 envValues
->reserve( argumentOrder_
->size( ) );
147 while( envValues
->size( ) < argumentOrder_
->size( ) )
149 envValues
->push_back( NullPtr
< Kernel::Variable
>( ) );
152 std::vector
< Kernel::StateHandle
> * envStates
= new std::vector
< Kernel::StateHandle
>;
153 envStates
->reserve( stateOrder_
->size( ) );
154 while( envStates
->size( ) < stateOrder_
->size( ) )
156 envStates
->push_back( NullPtr
< Kernel::State
>( ) );
159 evalState
->env_
= new Kernel::Environment( Kernel::theEnvironmentList
, evalState
->env_
, argumentOrder_
, RefCountPtr
< std::vector
< Kernel::VariableHandle
> >( envValues
), stateOrder_
, RefCountPtr
< std::vector
< Kernel::StateHandle
> >( envStates
) );
161 if( dynamicMap_
!= 0 )
163 evalState
->env_
->setupDynamicKeyVariables( dynamicMap_
);
166 RefCountPtr
< const Kernel::CodeBracketContInfo
> info( new Kernel::CodeBracketContInfo( this, *evalState
) );
168 evalAt( info
, nodes_
->begin( ), evalState
);
172 Ast::CodeBracket::evalAt( const RefCountPtr
< const Kernel::CodeBracketContInfo
> & info
, const std::list
< Ast::Node
* >::const_iterator
& pos
, Kernel::EvalState
* evalState
) const
175 std::list
< Ast::Node
* >::const_iterator next
= pos
;
177 if( next
== nodes_
->end( ) )
179 const Ast::Expression
* e
= dynamic_cast< const Ast::Expression
* >( *pos
);
183 evalState
->cont_
= Kernel::ContRef( new Kernel::ForcingContinuation( info
->cont_
, (*pos
)->loc( ) ) );
187 evalState
->cont_
= info
->cont_
;
192 evalState
->cont_
= Kernel::ContRef( new Kernel::CodeBracketContinuation( (*pos
)->loc( ), info
, next
) );
195 evalState
->env_
= info
->env_
;
196 evalState
->dyn_
= info
->dyn_
;
197 (*pos
)->eval( evalState
);
201 Kernel::CodeBracketContInfo::CodeBracketContInfo( const Ast::CodeBracket
* bracketExpr
, const Kernel::EvalState
& evalState
)
202 : bracketExpr_( bracketExpr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
205 Kernel::CodeBracketContInfo::~CodeBracketContInfo( )
209 Kernel::CodeBracketContInfo::gcMark( Kernel::GCMarkedSet
& marked
)
211 env_
->gcMark( marked
);
212 dyn_
->gcMark( marked
);
213 cont_
->gcMark( marked
);
216 Kernel::CodeBracketContinuation::CodeBracketContinuation( const Ast::SourceLocation
& traceLoc
, const RefCountPtr
< const Kernel::CodeBracketContInfo
> & info
, const std::list
< Ast::Node
* >::const_iterator
& pos
)
217 : Kernel::Continuation( traceLoc
), info_( info
), pos_( pos
)
220 Kernel::CodeBracketContinuation::~CodeBracketContinuation( )
224 Kernel::CodeBracketContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
226 if( val
.down_cast
< const Lang::Void
>( ) == NullPtr
< const Lang::Void
>( ) )
228 throw Exceptions::NonVoidStatement( traceLoc_
, val
);
230 info_
->bracketExpr_
->evalAt( info_
,
236 Kernel::CodeBracketContinuation::backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
238 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "code bracket" ) );
239 info_
->cont_
->backTrace( trace
);
243 Kernel::CodeBracketContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
245 const_cast< Kernel::CodeBracketContInfo
* >( info_
.getPtr( ) )->gcMark( marked
);
249 Ast::LexiographicVariable::LexiographicVariable( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
250 : Ast::Expression( loc
), id_( id
), idKey_( idKey
)
255 Ast::LexiographicVariable::~LexiographicVariable( )
262 delete idKey_
; // This can be done only as long as this is not shared!
266 Ast::LexiographicVariable::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
272 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( loc_
, id_
) );
279 Ast::LexiographicVariable::eval( Kernel::EvalState
* evalState
) const
281 evalState
->env_
->lookup( **idKey_
, evalState
);
285 Ast::EvalOutsideExpr::EvalOutsideExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
286 : Ast::Expression( loc
), expr_( expr
)
291 Ast::EvalOutsideExpr::~EvalOutsideExpr( )
297 Ast::EvalOutsideExpr::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
301 expr_
->analyze( this, env
->getParent( ) );
303 imperative_
= expr_
->imperative_
;
307 Ast::EvalOutsideExpr::eval( Kernel::EvalState
* evalState
) const
309 evalState
->expr_
= expr_
;
310 evalState
->env_
= evalState
->env_
->getParent( );
314 Ast::MemberReferenceFunction::MemberReferenceFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* variable
, const char * fieldID
)
315 : Lang::Function( new Kernel::EvaluatedFormals( "<>.<>", true ) ), loc_( loc
), variable_( variable
), fieldID_( fieldID
)
318 Ast::MemberReferenceFunction::~MemberReferenceFunction( )
325 Ast::MemberReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
327 args
->orderedExprs_
->push_back( variable_
);
331 Ast::MemberReferenceFunction::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
333 /* The variable is analyzed as part of the arguments passed to this function, so nothing needs to be done here...
334 * unless we would be able to figure out the type of the argument, and then check if the field reference is valid.
339 Ast::MemberReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
341 Kernel::ContRef cont
= evalState
->cont_
;
342 RefCountPtr
< const Lang::Value
> arg
= args
.getValue( 0 );
343 cont
->takeHandle( arg
->getField( fieldID_
, arg
),
349 Ast::MutatorReference::MutatorReference( const Ast::SourceLocation
& mutatorLoc
, Ast::StateReference
* state
, const char * mutatorID
)
350 : Ast::Expression( mutatorLoc
), mutatorLoc_( mutatorLoc
), state_( state
), mutatorID_( mutatorID
)
353 Ast::MutatorReference::~MutatorReference( )
355 /* At the time of implementing this bug-fix, state_ will allways be owned by the Ast::CallExpr that is also the owner of us.
356 * Hence, we do not consider ourselves owners. Perhaps one should have a flag indicating whether ownership is transferred
357 * when calling the constructor, but at the moment this seems like a waste of resources.
364 Ast::MutatorReference::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
366 state_
->analyze( this, env
);
370 /* If the type of the state was known here, we should verify that there is a mutator corresponding to the message <mutatorID>.
375 Ast::MutatorReference::eval( Kernel::EvalState
* evalState
) const
377 Kernel::ContRef cont
= evalState
->cont_
;
378 cont
->takeValue( state_
->getHandle( evalState
->env_
, evalState
->dyn_
)->getMutator( mutatorID_
),
384 Ast::SpecialLength::SpecialLength( const Ast::SourceLocation
& loc
, double val
, int sort
)
385 : Ast::Expression( loc
), val_( val
), sort_( sort
)
388 Ast::SpecialLength::~SpecialLength( )
392 Ast::SpecialLength::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
400 Ast::SpecialLength::eval( Kernel::EvalState
* evalState
) const
406 evalState
->dyn_
->specialUnitService( & d
, & a0
, & a1
);
408 if( sort_
== Computation::SPECIALU_NOINFLEX
)
410 Kernel::ContRef cont
= evalState
->cont_
;
411 cont
->takeValue( Kernel::ValueRef( new Lang::Length( val_
* d
* Computation::specialUnitNoInflexion( a0
, a1
) ) ),
415 if( ! sort_
& Computation::SPECIALU_DIST
)
417 throw Exceptions::InternalError( strrefdup( "The special unit is neither based on inflexion or distance" ) );
422 if( sort_
& Computation::SPECIALU_CIRC
)
424 res
*= Computation::specialUnitCircleHandle( a0
);
427 if( sort_
& Computation::SPECIALU_CORR
)
429 res
*= Computation::specialUnitCorrection( a0
, a1
);
432 if( sort_
& Computation::SPECIALU_NOINFLEX
)
434 res
= min( res
, Computation::specialUnitNoInflexion( a0
, a1
) );
436 Kernel::ContRef cont
= evalState
->cont_
;
437 cont
->takeValue( Kernel::ValueRef( new Lang::Length( val_
* d
* res
) ),
442 Ast::DynamicVariable::DynamicVariable( const Ast::SourceLocation
& loc
, const char * id
)
443 : Ast::Expression( loc
), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
448 Ast::DynamicVariable::~DynamicVariable( )
455 delete idKey_
; // This can be done only as long as this is not shared!
459 Ast::DynamicVariable::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
465 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( loc_
, id_
) );
472 Ast::DynamicVariable::eval( Kernel::EvalState
* evalState
) const
474 const Kernel::DynamicVariableProperties
& dynProps
= evalState
->env_
->lookupDynamicVariable( **idKey_
);
476 Kernel::VariableHandle res
= dynProps
.fetch( evalState
->dyn_
);
478 /* Now, we know that if the value was bound to a dynamic expression, a value was bound, and that value has
481 if( ! res
->isThunk( ) )
485 typedef const Lang::DynamicExpression DynType
;
486 RefCountPtr
< DynType
> dynVal
= res
->tryVal
< DynType
>( );
487 dynVal
->eval( evalState
);
490 catch( const NonLocalExit::NotThisType
& ball
)
496 Kernel::ContRef cont
= evalState
->cont_
;
497 cont
->takeHandle( res
,
502 Kernel::DynamicBindingContinuation::DynamicBindingContinuation( const Ast::SourceLocation
& traceLoc
, const Kernel::PassedEnv
& env
, const Kernel::Environment::LexicalKey
& key
, const Ast::SourceLocation
& idLoc
, const Kernel::ContRef
& cont
)
503 : Kernel::Continuation( traceLoc
), env_( env
), key_( key
), idLoc_( idLoc
), cont_( cont
)
506 Kernel::DynamicBindingContinuation::~DynamicBindingContinuation( )
510 Kernel::DynamicBindingContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
512 if( val
->isThunk( ) )
514 val
->force( val
, evalState
);
517 evalState
->cont_
= cont_
;
518 env_
->lookupDynamicVariable( key_
).makeBinding( val
, idLoc_
, evalState
);
522 Kernel::DynamicBindingContinuation::backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
524 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "dynamic binding" ) );
525 cont_
->backTrace( trace
);
529 Kernel::DynamicBindingContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
531 env_
->gcMark( marked
);
532 cont_
->gcMark( marked
);
535 Ast::DynamicBindingExpression::DynamicBindingExpression( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, Kernel::Environment::LexicalKey
** idKey
)
536 : Ast::Expression( Ast::SourceLocation( idLoc
, expr
->loc( ) ) ), idLoc_( idLoc
), id_( id
), expr_( expr
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
539 Ast::DynamicBindingExpression::~DynamicBindingExpression( )
548 // Don't delete idKey as it's shared!
552 Ast::DynamicBindingExpression::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
556 expr_
->analyze( this, env
);
559 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( idLoc_
, id_
) );
562 imperative_
= expr_
->imperative_
;
566 Ast::DynamicBindingExpression::eval( Kernel::EvalState
* evalState
) const
568 const Kernel::DynamicVariableProperties
& dynProps
= evalState
->env_
->lookupDynamicVariable( **idKey_
);
570 if( dynProps
.forceValue( ) || expr_
->immediate_
)
572 evalState
->expr_
= expr_
;
573 evalState
->cont_
= Kernel::ContRef( new Kernel::DynamicBindingContinuation( expr_
->loc( ), evalState
->env_
, **idKey_
, idLoc_
, evalState
->cont_
) );
577 dynProps
.makeBinding( Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( evalState
->env_
, evalState
->dyn_
, expr_
) ) ),
584 Ast::DynamicStateBindingExpression::DynamicStateBindingExpression( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& dstLoc
, const char * dstId
, Ast::StateReference
* src
)
585 : Ast::Expression( loc
), dstLoc_( dstLoc
), dstId_( dstId
), dstIdKey_( new Kernel::Environment::LexicalKey
* ( 0 ) ), src_( src
)
588 Ast::DynamicStateBindingExpression::~DynamicStateBindingExpression( )
591 if( *dstIdKey_
!= 0 )
595 delete dstIdKey_
; // This can be done only as long as this is not shared!
599 Ast::DynamicStateBindingExpression::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
603 if( *dstIdKey_
== 0 )
605 *dstIdKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( dstLoc_
, dstId_
) );
612 Ast::DynamicStateBindingExpression::eval( Kernel::EvalState
* evalState
) const
614 const Kernel::DynamicStateProperties
& dstDynProps
= evalState
->env_
->lookupDynamicState( **dstIdKey_
);
616 dstDynProps
.makeBinding( src_
->getHandle( evalState
->env_
, evalState
->dyn_
), dstLoc_
, evalState
);
620 Kernel::WithDynamicContinuation::WithDynamicContinuation( const Ast::SourceLocation
& traceLoc
, Ast::Expression
* expr
, const Kernel::EvalState
& evalState
)
621 : Kernel::Continuation( traceLoc
), expr_( expr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
624 Kernel::WithDynamicContinuation::~WithDynamicContinuation( )
628 Kernel::WithDynamicContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
630 evalState
->dyn_
= Kernel::PassedDyn( new Kernel::DynamicEnvironment( dyn_
, *Helpers::down_cast
< const Lang::DynamicBindings
>( val
, traceLoc_
) ) );
631 evalState
->env_
= env_
;
632 evalState
->expr_
= expr_
;
633 evalState
->cont_
= cont_
;
637 Kernel::WithDynamicContinuation::backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
639 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "with dynamic bindings" ) );
640 cont_
->backTrace( trace
);
644 Kernel::WithDynamicContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
646 env_
->gcMark( marked
);
647 dyn_
->gcMark( marked
);
648 cont_
->gcMark( marked
);
652 Ast::WithDynamicExpr::WithDynamicExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* bindings
, Ast::Expression
* expr
)
653 : Ast::Expression( loc
), bindings_( bindings
), expr_( expr
)
656 Ast::WithDynamicExpr::~WithDynamicExpr( )
660 Ast::WithDynamicExpr::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
664 bindings_
->analyze( this, env
);
665 expr_
->analyze( this, env
);
667 imperative_
= bindings_
->imperative_
|| expr_
->imperative_
;
671 Ast::WithDynamicExpr::eval( Kernel::EvalState
* evalState
) const
673 evalState
->expr_
= bindings_
;
674 evalState
->cont_
= Kernel::ContRef( new Kernel::WithDynamicContinuation( bindings_
->loc( ), expr_
, *evalState
) );
678 Ast::DynamicVariableDecl::DynamicVariableDecl( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* filterExpr
, Ast::Expression
* defaultExpr
)
679 : Ast::BindNode( loc
, idLoc
, id
), idPos_( new size_t * ( 0 ) )
681 /* This type of expression is an Ast::BindNode so that it is easy to recognize and extract the identifier for static analysis
684 * The expression is implemented as a function call, since there are two subexpressions that may need evaluation.
687 Ast::ArgListExprs
* args
= new Ast::ArgListExprs( false );
688 Ast::DynamicVariableDeclFunction
* res
= new Ast::DynamicVariableDeclFunction( id
, filterExpr
, defaultExpr
, idPos_
);
689 res
->push_exprs( args
);
690 impl_
= new Ast::CallExpr( loc
,
691 RefCountPtr
< const Lang::Function
>( res
),
695 Ast::DynamicVariableDecl::~DynamicVariableDecl( )
699 Ast::DynamicVariableDecl::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
703 impl_
->analyze( this, env
);
706 *idPos_
= new size_t( env
->findLocalDynamicPosition( idLoc_
, id_
) );
709 imperative_
= impl_
->imperative_
;
713 Ast::DynamicVariableDecl::eval( Kernel::EvalState
* evalState
) const
715 evalState
->expr_
= impl_
;
719 Ast::DynamicVariableDeclFunction::DynamicVariableDeclFunction( const char * id
, Ast::Expression
* filterExpr
, Ast::Expression
* defaultExpr
, size_t ** idPos
)
720 : Lang::Function( new Kernel::EvaluatedFormals( "< dynamic variable declaration >", false ) ), id_( id
), filterExpr_( filterExpr
), defaultExpr_( defaultExpr
), idPos_( idPos
)
723 Ast::DynamicVariableDeclFunction::~DynamicVariableDeclFunction( )
730 Ast::DynamicVariableDeclFunction::push_exprs( Ast::ArgListExprs
* args
) const
732 args
->orderedExprs_
->push_back( filterExpr_
);
733 args
->orderedExprs_
->push_back( defaultExpr_
);
737 Ast::DynamicVariableDeclFunction::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
739 /* The analysis is carried out by the DynamicVariableDecl expression.
744 Ast::DynamicVariableDeclFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
746 static const char * title
= "< dynamic variable declaration >";
747 typedef const Lang::Function FilterType
;
748 evalState
->env_
->defineDynamic( id_
,
750 Helpers::down_cast_CoreArgument
< FilterType
>( title
, args
, 0, callLoc
),
751 args
.getHandle( 1 ) );
753 Kernel::ContRef cont
= evalState
->cont_
;
754 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
758 Kernel::DynamicVariableDeclContinuation::DynamicVariableDeclContinuation( const Ast::SourceLocation
& traceLoc
, const Ast::DynamicVariableDecl
* declExpr
, Kernel::EvalState
& evalState
)
759 : Kernel::Continuation( traceLoc
), declExpr_( declExpr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
762 Kernel::DynamicVariableDeclContinuation::~DynamicVariableDeclContinuation( )
766 Kernel::DynamicVariableDeclContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
768 evalState
->env_
= env_
;
769 evalState
->dyn_
= dyn_
;
770 evalState
->cont_
= cont_
;
771 throw Exceptions::NotImplemented( "Deprecated: DynamicVariableDeclContinuation" );
772 // declExpr_->callBack( Helpers::down_cast< const Lang::Function >( val, traceLoc_ ),
777 Kernel::DynamicVariableDeclContinuation::backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
779 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "dynamic variable declaration" ) );
780 cont_
->backTrace( trace
);
784 Kernel::DynamicVariableDeclContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
786 env_
->gcMark( marked
);
787 dyn_
->gcMark( marked
);
788 cont_
->gcMark( marked
);
792 Ast::DynamicStateDecl::DynamicStateDecl( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::StateReference
* defaultState
, size_t ** idPos
)
793 : Ast::BindNode( loc
, idLoc
, id
), idPos_( idPos
), defaultState_( defaultState
)
796 Ast::DynamicStateDecl::~DynamicStateDecl( )
801 Ast::DynamicStateDecl::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
807 *idPos_
= new size_t( env
->findLocalDynamicStatePosition( idLoc_
, id_
) );
814 Ast::DynamicStateDecl::eval( Kernel::EvalState
* evalState
) const
816 evalState
->env_
->defineDynamicState( id_
,
821 Kernel::ContRef cont
= evalState
->cont_
;
822 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
,
827 Ast::EvalSymbolFunction::EvalSymbolFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
828 : Lang::Function( new Kernel::EvaluatedFormals( "< symbol evaluation >", true ) ), loc_( loc
), expr_( expr
)
831 Ast::EvalSymbolFunction::~EvalSymbolFunction( )
837 Ast::EvalSymbolFunction::push_exprs( Ast::ArgListExprs
* args
) const
839 args
->orderedExprs_
->push_back( expr_
);
843 Ast::EvalSymbolFunction::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
847 /* expr_ shall be analyzed from the calling expression.
848 * Here, it is only used to locate errors.
853 Ast::EvalSymbolFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
855 RefCountPtr
< const Lang::Value
> untypedVal
= args
.getValue( 0 );
856 typedef const Lang::Symbol ArgType
;
857 ArgType
* val
= dynamic_cast< ArgType
* >( untypedVal
.getPtr( ) );
860 throw Exceptions::TypeMismatch( expr_
->loc( ), untypedVal
->getTypeName( ), ArgType::staticTypeName( ) );
862 if( val
->isUnique( ) )
864 throw Exceptions::OutOfRange( expr_
->loc( ), strrefdup( "Unique symbols can't denote variables." ) );
868 Kernel::Environment::LexicalKey key
= analysisEnv_
->findLexicalVariableKey( loc_
, val
->name( ).getPtr( ) );
870 Kernel::PassedEnv env
= evalState
->env_
;
871 env
->lookup( key
, evalState
);
875 Ast::DefineVariable::DefineVariable( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, size_t ** idPos
)
876 : Ast::BindNode( Ast::SourceLocation( idLoc
, expr
->loc( ) ), idLoc
, id
), expr_( expr
), idPos_( idPos
)
879 Ast::DefineVariable::~DefineVariable( )
883 /* idPos_ is shared and will be a memory leak which must not be deleted.
884 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
890 Ast::DefineVariable::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
894 expr_
->analyze( this, env
);
897 *idPos_
= new size_t( env
->findLocalVariablePosition( idLoc_
, id_
) );
900 imperative_
= expr_
->imperative_
;
904 Ast::DefineVariable::eval( Kernel::EvalState
* evalState
) const
906 if( expr_
->immediate_
|| expr_
->imperative_
)
908 evalState
->cont_
= Kernel::ContRef( new Kernel::DefineVariableContinuation( evalState
->env_
,
912 evalState
->expr_
= expr_
;
916 evalState
->env_
->define( **idPos_
,
917 Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( evalState
->env_
,
920 Kernel::ContRef cont
= evalState
->cont_
;
921 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
, evalState
);
926 Kernel::AssertStructureContinuation::AssertStructureContinuation( const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
927 : Kernel::Continuation( traceLoc
), cont_( cont
)
930 Kernel::AssertStructureContinuation::~AssertStructureContinuation( )
934 Kernel::AssertStructureContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
936 evalState
->cont_
= cont_
;
937 cont_
->takeValue( Helpers::down_cast_ContinuationArgument
< const Lang::Structure
>( val
, this ), evalState
);
941 Kernel::AssertStructureContinuation::backTrace( std::list
< Kernel::Continuation::BackTraceElem
> * trace
) const
943 trace
->push_front( Kernel::Continuation::BackTraceElem( this, "Assert type is struct" ) );
944 cont_
->backTrace( trace
);
948 Kernel::AssertStructureContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
950 cont_
->gcMark( marked
);
954 Ast::StructSplitReference::StructSplitReference( Ast::SourceLocation fieldLoc
, const char * fieldId
, Ast::Expression
* defaultExpr
)
955 : Ast::Expression( fieldLoc
),
956 structLoc_( Ast::THE_UNKNOWN_LOCATION
), // This is a dummy value! The correct value is set later.
958 defaultExpr_( defaultExpr
)
961 Ast::StructSplitReference::StructSplitReference( Ast::SourceLocation fieldLoc
, size_t fieldPos
, Ast::Expression
* defaultExpr
)
962 : Ast::Expression( fieldLoc
),
963 structLoc_( Ast::THE_UNKNOWN_LOCATION
), // This is a dummy value! The correct value is set later.
964 fieldId_( 0 ), fieldPos_( fieldPos
),
965 defaultExpr_( defaultExpr
)
968 Ast::StructSplitReference::~StructSplitReference( )
974 if( defaultExpr_
!= 0 )
981 Ast::StructSplitReference::setStruct( Ast::SourceLocation structLoc
, size_t ** structPos
)
983 structLoc_
= structLoc
;
984 structPos_
= structPos
;
988 Ast::StructSplitReference::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
992 if( defaultExpr_
!= 0 )
994 defaultExpr_
->analyze( this, env
);
995 imperative_
= defaultExpr_
->imperative_
;
1004 Ast::StructSplitReference::eval( Kernel::EvalState
* evalState
) const
1006 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1007 typedef const Lang::Structure StructType
;
1008 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1010 Kernel::ContRef cont
= evalState
->cont_
;
1015 cont
->takeHandle( structVal
->getField( fieldId_
, structVal
),
1019 catch( const Exceptions::NonExistentMember
& ball
)
1021 if( defaultExpr_
== 0 )
1025 // Never mind, we use the default instead. See below.
1032 cont
->takeHandle( structVal
->getPosition( fieldPos_
, structVal
),
1036 catch( const Exceptions::NonExistentPosition
& ball
)
1038 if( defaultExpr_
== 0 )
1042 // Never mind, we use the default instead. See below.
1046 if( defaultExpr_
== 0 )
1048 throw Exceptions::InternalError( "Just about to use null pointer defaultExpr_ in StructSplitReference::eval." );
1050 evalState
->expr_
= defaultExpr_
;
1053 Ast::StructSplitSink::StructSplitSink( )
1054 : Ast::Expression( Ast::THE_UNKNOWN_LOCATION
), structLoc_( Ast::THE_UNKNOWN_LOCATION
)
1057 Ast::StructSplitSink::~StructSplitSink( )
1061 Ast::StructSplitSink::setStruct( Ast::SourceLocation structLoc
, size_t ** structPos
, size_t consumedArguments
)
1063 structLoc_
= structLoc
;
1064 structPos_
= structPos
;
1065 consumedArguments_
= consumedArguments
;
1069 Ast::StructSplitSink::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1073 imperative_
= false;
1077 Ast::StructSplitSink::eval( Kernel::EvalState
* evalState
) const
1079 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1080 typedef const Lang::Structure StructType
;
1081 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1083 Kernel::ContRef cont
= evalState
->cont_
;
1084 cont
->takeValue( structVal
->getSink( consumedArguments_
),
1089 Ast::AssertNoSinkNeeded::AssertNoSinkNeeded( const Ast::SourceLocation
& loc
, size_t orderedCount
, Ast::SourceLocation structLoc
, size_t ** structPos
)
1090 : Ast::Expression( loc
), orderedCount_( orderedCount
), structLoc_( structLoc
), structPos_( structPos
)
1093 Ast::AssertNoSinkNeeded::~AssertNoSinkNeeded( )
1097 Ast::AssertNoSinkNeeded::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1105 Ast::AssertNoSinkNeeded::eval( Kernel::EvalState
* evalState
) const
1107 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1108 typedef const Lang::Structure StructType
;
1109 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1111 if( structVal
->argList_
->orderedExprs_
->size( ) > orderedCount_
)
1113 throw Exceptions::SinkRequired( loc_
, orderedCount_
, structVal
->argList_
->orderedExprs_
->size( ) );
1116 Kernel::ContRef cont
= evalState
->cont_
;
1117 cont
->takeHandle( Kernel::THE_SLOT_VARIABLE
, evalState
);
1120 size_t Ast::SplitDefineVariables::splitVarCount
= 0;
1121 PtrOwner_back_Access
< std::list
< const char * > > Ast::SplitDefineVariables::mem
;
1123 Ast::SplitDefineVariables::SplitDefineVariables( )
1124 : sinkDefine_( 0 ), sinkExpr_( 0 ), seenNamed_( false ), seenDefault_( false )
1126 std::ostringstream oss
;
1127 oss
<< Kernel::SPLIT_VAR_PREFIX
<< splitVarCount
;
1128 splitVarId_
= strdup( oss
.str( ).c_str( ) );
1129 mem
.push_back( splitVarId_
);
1134 Ast::SplitDefineVariables::newSplitVarId( ) const
1136 return strdup( splitVarId_
);
1140 Ast::StateReference::StateReference( const Ast::SourceLocation
& loc
)
1144 Ast::StateReference::~StateReference( )
1148 Ast::StateReference::eval( Kernel::EvalState
* evalState
) const
1150 throw Exceptions::InternalError( "A state reference was evaluated." );
1154 Ast::LexiographicState::LexiographicState( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
1155 : Ast::StateReference( loc
), id_( id
), idKey_( idKey
)
1158 Ast::LexiographicState::~LexiographicState( )
1165 delete idKey_
; // This can be done only as long as this is not shared!
1169 Ast::LexiographicState::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1175 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalStateKey( loc_
, id_
) );
1182 Ast::LexiographicState::getHandle( Kernel::PassedEnv env
, Kernel::PassedDyn dyn
) const
1184 return env
->getStateHandle( **idKey_
);
1188 Ast::DynamicState::DynamicState( const Ast::SourceLocation
& loc
, const char * id
)
1189 : Ast::StateReference( loc
), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
1192 Ast::DynamicState::~DynamicState( )
1199 delete idKey_
; // This can be done only as long as this is not shared!
1203 Ast::DynamicState::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1207 /* It would make sense to check the reference and...
1213 Ast::DynamicState::getHandle( Kernel::PassedEnv env
, Kernel::PassedDyn dyn
) const
1215 throw Exceptions::NotImplemented( "Referencing dynamic states" );
1219 Ast::IntroduceState::IntroduceState( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, size_t ** idPos
)
1220 : Ast::BindNode( Ast::SourceLocation( idLoc
, expr
->loc( ) ), idLoc
, id
), expr_( expr
), idPos_( idPos
)
1223 Ast::IntroduceState::~IntroduceState( )
1227 /* idPos_ shared and will be a memory leak which must not be deleted.
1228 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1234 Ast::IntroduceState::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1238 expr_
->analyze( this, env
);
1242 *idPos_
= new size_t( env
->findLocalStatePosition( idLoc_
, id_
) );
1245 imperative_
= expr_
->imperative_
;
1249 Ast::IntroduceState::eval( Kernel::EvalState
* evalState
) const
1251 evalState
->cont_
= Kernel::ContRef( new Kernel::IntroduceStateContinuation( evalState
->env_
,
1255 evalState
->expr_
= expr_
;
1259 Ast::Insertion::Insertion( Ast::StateReference
* stateRef
, Ast::Expression
* expr
)
1260 : Ast::Node( Ast::SourceLocation( stateRef
->loc( ), expr
->loc( ) ) ), stateRef_( stateRef
), expr_( expr
)
1263 Ast::Insertion::~Insertion( )
1267 Ast::Insertion::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1271 stateRef_
->analyze( this, env
);
1272 expr_
->analyze( this, env
);
1278 Ast::Insertion::eval( Kernel::EvalState
* evalState
) const
1280 evalState
->cont_
= Kernel::ContRef( new Kernel::InsertionContinuation( stateRef_
->getHandle( evalState
->env_
, evalState
->dyn_
),
1284 evalState
->expr_
= expr_
;
1287 Ast::Freeze::Freeze( const Ast::SourceLocation
& idLoc
, const char * id
, size_t ** idPos
)
1288 : Ast::Expression( idLoc
), id_( id
), idPos_( idPos
)
1293 Ast::Freeze::~Freeze( )
1295 /* idPos shared and will be a memory leak which must not be deleted.
1296 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1301 Ast::Freeze::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1307 *idPos_
= new size_t( env
->findLocalStatePosition( loc( ), id_
) );
1314 Ast::Freeze::eval( Kernel::EvalState
* evalState
) const
1316 evalState
->env_
->freeze( **idPos_
, evalState
, loc( ) );
1320 Ast::Peek::Peek( const Ast::SourceLocation
& idLoc
, Ast::StateReference
* stateRef
)
1321 : Ast::Expression( idLoc
), stateRef_( stateRef
)
1328 /* idPos shared and will be a memory leak which must not be deleted.
1329 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1334 Ast::Peek::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1338 stateRef_
->analyze( this, env
);
1344 Ast::Peek::eval( Kernel::EvalState
* evalState
) const
1346 stateRef_
->getHandle( evalState
->env_
, evalState
->dyn_
)->peek( evalState
, loc( ) );
1350 Ast::DynamicExpression::DynamicExpression( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
1351 : Ast::Expression( loc
), expr_( expr
)
1356 Ast::DynamicExpression::~DynamicExpression( )
1360 Ast::DynamicExpression::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1364 expr_
->analyze( this, env
);
1366 if( expr_
->imperative_
)
1368 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IllegalImperative( expr_
->loc( ) ) );
1370 imperative_
= false;
1374 Ast::DynamicExpression::eval( Kernel::EvalState
* evalState
) const
1376 Kernel::ContRef cont
= evalState
->cont_
;
1377 cont
->takeValue( Kernel::ValueRef( new Lang::DynamicExpression( evalState
->env_
, expr_
) ),
1382 Ast::LexiographicType::LexiographicType( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
1383 : Ast::Expression( loc
), id_( id
), idKey_( idKey
)
1388 Ast::LexiographicType::~LexiographicType( )
1395 delete idKey_
; // This can be done only as long as this is not shared!
1399 Ast::LexiographicType::analyze( Ast::Node
* parent
, const Ast::AnalysisEnvironment
* env
)
1405 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalTypeKey( loc_
, id_
) );
1408 imperative_
= false;
1412 Ast::LexiographicType::eval( Kernel::EvalState
* evalState
) const
1414 evalState
->env_
->lookup( **idKey_
, evalState
);