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
20 #include "shapesexceptions.h"
22 #include "autoonoff.h"
23 #include "specialunits.h"
25 #include "continuations.h"
26 #include "containertypes.h"
31 using namespace Shapes
;
35 Ast::SourceLocationMark::SourceLocationMark( const Ast::SourceLocation
& loc
)
39 Ast::SourceLocationMark::~SourceLocationMark( )
43 Ast::SourceLocationMark::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
50 class IsSourceLocationMark
53 bool operator () ( const Ast::Node
* n
) const
55 return dynamic_cast< const Ast::SourceLocationMark
* >( n
) != 0;
62 Ast::CodeBracket::CodeBracket( const Ast::SourceLocation
& loc
, std::list
< Ast::Node
* > * nodes
, Ast::CodeBracket
* extends
)
63 : Ast::Expression( loc
), nodes_( nodes
), extends_( extends
),
64 argumentOrder_( ( extends
== 0 ) ? ( new typeof *argumentOrder_
) : ( extends
->argumentOrder_
) ),
65 dynamicMap_( ( extends
== 0 ) ? ( 0 ) : ( extends
->dynamicMap_
) ),
66 stateOrder_( ( extends
== 0 ) ? ( new typeof *stateOrder_
) : ( extends
->stateOrder_
) )
68 /* First, we remove any source location marks -- we don't need them anymore. */
69 nodes_
->remove_if( Helpers::IsSourceLocationMark( ) );
71 for( std::list
< Ast::Node
* >::const_iterator i
= nodes_
->begin( );
75 typedef const Ast::BindNode T
;
76 T
* tmp
= dynamic_cast< T
* >( *i
);
79 const char * name
= tmp
->id( );
81 typedef const Ast::DefineVariable T
;
82 T
* decl
= dynamic_cast< T
* >( tmp
);
85 if( argumentOrder_
->find( name
) != argumentOrder_
->end( ) )
87 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
90 argumentOrder_
->insert( std::pair
< const char *, size_t >( name
, argumentOrder_
->size( ) ) );
95 typedef const Ast::IntroduceState T
;
96 T
* decl
= dynamic_cast< T
* >( tmp
);
99 if( stateOrder_
->find( name
) != stateOrder_
->end( ) )
101 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
104 stateOrder_
->insert( std::pair
< const char *, size_t >( name
, stateOrder_
->size( ) ) );
109 typedef const Ast::DynamicVariableDecl T
;
110 T
* dynDecl
= dynamic_cast< T
* >( tmp
);
113 if( dynamicMap_
== 0 )
115 setDynamicMap( new std::map
< const char *, size_t, charPtrLess
> ); /* Sending the new map to extends_ recursively is important for memory management. */
117 if( dynamicMap_
->find( name
) != dynamicMap_
->end( ) )
119 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IntroducingExisting( tmp
->idLoc( ), name
) );
122 dynamicMap_
->insert( std::pair
< const char *, size_t >( name
, dynamicMap_
->size( ) ) );
131 Ast::CodeBracket::setDynamicMap( MapType
* dynamicMap
)
133 dynamicMap_
= dynamicMap
;
136 extends_
->setDynamicMap( dynamicMap
);
140 Ast::CodeBracket::~CodeBracket( )
142 typedef list
< Ast::Node
* >::iterator I
;
143 for( I i
= nodes_
->begin( ); i
!= nodes_
->end( ); ++i
)
151 /* If extends_ != 0, this object does not own the maps. */
152 delete argumentOrder_
;
153 if( dynamicMap_
!= 0 )
162 Ast::CodeBracket::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* parentEnv
, Ast::StateIDSet
* freeStatesDst
)
166 analysisEnv_
= new Ast::AnalysisEnvironment( Ast::theAnalysisEnvironmentList
, parentEnv
, argumentOrder_
, stateOrder_
);
170 analysisEnv_
= extends_
->analysisEnv_
;
171 analysisEnv_
->updateBindings( );
174 if( dynamicMap_
!= 0 )
176 analysisEnv_
->setupDynamicKeyVariables( dynamicMap_
);
180 Ast::StateIDSet allFreeStates
;
181 Ast::StateIDSet introducedStates
;
184 Ast::StateIDSet freeStates
;
185 typedef list
< Ast::Node
* >::iterator I
;
186 for( I i
= nodes_
->begin( ); i
!= nodes_
->end( ); ++i
)
189 (*i
)->analyze( this, analysisEnv_
, & freeStates
);
190 if( ! freeStates
.empty( ) )
192 typedef typeof freeStates SetType
;
193 for( SetType::const_iterator j
= freeStates
.begin( ); j
!= freeStates
.end( ); ++j
)
195 allFreeStates
.insert( *j
);
200 Ast::Expression
* expr
= dynamic_cast< Ast::Expression
* >( *i
);
201 if( expr
!= 0 && ! expr
->immediate_
)
205 if( tmp
!= nodes_
->end( ) )
207 Ast::theAnalysisErrorsList
.push_back( new Exceptions::ExpectedImmediate( (*i
)->loc( ) ) );
211 Ast::IntroduceState
* introduceStateExpr
= dynamic_cast< Ast::IntroduceState
* >( *i
);
212 if( introduceStateExpr
!= 0 )
214 introducedStates
.insert( introduceStateExpr
->getStateID( ) );
219 if( ! introducedStates
.empty( ) )
221 Ast::StateIDSet diff
;
222 std::set_difference( allFreeStates
.begin( ), allFreeStates
.end( ),
223 introducedStates
.begin( ), introducedStates
.end( ),
224 std::inserter( diff
, diff
.begin( ) ) );
225 allFreeStates
.swap( diff
);
227 if( ! allFreeStates
.empty( ) )
229 typedef typeof allFreeStates SetType
;
230 for( SetType::const_iterator j
= allFreeStates
.begin( ); j
!= allFreeStates
.end( ); ++j
)
232 freeStatesDst
->insert( *j
);
238 Ast::CodeBracket::eval( Kernel::EvalState
* evalState
) const
240 if( nodes_
->begin( ) == nodes_
->end( ) )
242 Kernel::ContRef cont
= evalState
->cont_
;
243 cont
->takeValue( Lang::THE_VOID
,
248 evalState
->env_
= newEnvironment( evalState
->env_
);
250 if( dynamicMap_
!= 0 )
252 evalState
->env_
->setupDynamicKeyVariables( dynamicMap_
);
255 RefCountPtr
< const Kernel::CodeBracketContInfo
> info( new Kernel::CodeBracketContInfo( this, *evalState
) );
257 evalAt( info
, nodes_
->begin( ), evalState
);
260 Kernel::Environment
*
261 Ast::CodeBracket::newEnvironment( Kernel::Environment
* parent
, const char * debugName
) const
266 throw Exceptions::InternalError( "Ast::CodeBracket::newEnvironment( ): extends_ != 0" );
269 std::vector
< Kernel::VariableHandle
> * envValues
= new std::vector
< Kernel::VariableHandle
>;
270 envValues
->reserve( argumentOrder_
->size( ) );
271 while( envValues
->size( ) < argumentOrder_
->size( ) )
273 envValues
->push_back( NullPtr
< Kernel::Variable
>( ) );
276 std::vector
< Kernel::StateHandle
> * envStates
= new std::vector
< Kernel::StateHandle
>;
277 envStates
->reserve( stateOrder_
->size( ) );
278 while( envStates
->size( ) < stateOrder_
->size( ) )
280 envStates
->push_back( NullPtr
< Kernel::State
>( ) );
283 return new Kernel::Environment( Kernel::theEnvironmentList
, parent
, argumentOrder_
, RefCountPtr
< std::vector
< Kernel::VariableHandle
> >( envValues
), stateOrder_
, RefCountPtr
< std::vector
< Kernel::StateHandle
> >( envStates
), debugName
);
287 Ast::CodeBracket::eval( Kernel::EvalState
* evalState
, Kernel::Environment
* extendsEnv
) const
289 if( nodes_
->begin( ) == nodes_
->end( ) )
291 Kernel::ContRef cont
= evalState
->cont_
;
292 cont
->takeValue( Lang::THE_VOID
,
297 evalState
->env_
= extendsEnv
;
298 if( dynamicMap_
!= 0 )
300 evalState
->env_
->setupDynamicKeyVariables( dynamicMap_
);
302 evalState
->env_
->extendVectors( );
304 RefCountPtr
< const Kernel::CodeBracketContInfo
> info( new Kernel::CodeBracketContInfo( this, *evalState
) );
306 evalAt( info
, nodes_
->begin( ), evalState
);
310 Ast::CodeBracket::evalAt( const RefCountPtr
< const Kernel::CodeBracketContInfo
> & info
, const std::list
< Ast::Node
* >::const_iterator
& pos
, Kernel::EvalState
* evalState
) const
312 Ast::Expression
* e
= dynamic_cast< Ast::Expression
* >( *pos
);
314 std::list
< Ast::Node
* >::const_iterator next
= pos
;
316 if( next
== nodes_
->end( ) )
321 evalState
->cont_
= Kernel::ContRef( new Kernel::ForcingContinuation( info
->cont_
, (*pos
)->loc( ) ) );
325 evalState
->cont_
= info
->cont_
;
330 evalState
->cont_
= Kernel::ContRef( new Kernel::CodeBracketContinuation( (*pos
)->loc( ), info
, next
) );
333 evalState
->env_
= info
->env_
;
334 evalState
->dyn_
= info
->dyn_
;
337 evalState
->expr_
= e
;
340 const Ast::BindNode
* bn
= dynamic_cast< const Ast::BindNode
* >( *pos
);
343 bn
->evalHelper( evalState
);
346 throw Exceptions::InternalError( (*pos
)->loc( ), "CodeBracket::evalAt: Node was neither Expression or BindNode." );
350 Kernel::CodeBracketContInfo::CodeBracketContInfo( const Ast::CodeBracket
* bracketExpr
, const Kernel::EvalState
& evalState
)
351 : bracketExpr_( bracketExpr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
354 Kernel::CodeBracketContInfo::~CodeBracketContInfo( )
358 Kernel::CodeBracketContInfo::gcMark( Kernel::GCMarkedSet
& marked
)
360 env_
->gcMark( marked
);
361 dyn_
->gcMark( marked
);
362 cont_
->gcMark( marked
);
365 Kernel::CodeBracketContinuation::CodeBracketContinuation( const Ast::SourceLocation
& traceLoc
, const RefCountPtr
< const Kernel::CodeBracketContInfo
> & info
, const std::list
< Ast::Node
* >::const_iterator
& pos
)
366 : Kernel::Continuation( traceLoc
), info_( info
), pos_( pos
)
369 Kernel::CodeBracketContinuation::~CodeBracketContinuation( )
373 Kernel::CodeBracketContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
375 if( val
.down_cast
< const Lang::Void
>( ) == NullPtr
< const Lang::Void
>( ) )
377 throw Exceptions::NonVoidStatement( traceLoc_
, val
);
379 info_
->bracketExpr_
->evalAt( info_
,
385 Kernel::CodeBracketContinuation::up( ) const
390 RefCountPtr
< const char >
391 Kernel::CodeBracketContinuation::description( ) const
393 return strrefdup( "code bracket" );
397 Kernel::CodeBracketContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
399 const_cast< Kernel::CodeBracketContInfo
* >( info_
.getPtr( ) )->gcMark( marked
);
403 Ast::LexiographicVariable::LexiographicVariable( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
404 : Ast::Expression( loc
), id_( id
), idKey_( idKey
)
409 Ast::LexiographicVariable::~LexiographicVariable( )
416 delete idKey_
; // This can be done only as long as this is not shared!
420 Ast::LexiographicVariable::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
424 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( loc_
, id_
) );
429 Ast::LexiographicVariable::eval( Kernel::EvalState
* evalState
) const
431 evalState
->env_
->lookup( **idKey_
, evalState
);
435 Ast::EvalOutsideExpr::EvalOutsideExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
436 : Ast::Expression( loc
), expr_( expr
)
441 Ast::EvalOutsideExpr::~EvalOutsideExpr( )
447 Ast::EvalOutsideExpr::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
449 expr_
->analyze( this, env
->getParent( ), freeStatesDst
);
453 Ast::EvalOutsideExpr::eval( Kernel::EvalState
* evalState
) const
455 evalState
->expr_
= expr_
;
456 evalState
->env_
= evalState
->env_
->getParent( );
460 Ast::MemberReferenceFunction::MemberReferenceFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* variable
, const char * fieldID
)
461 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "<>.<>" ), true ) ), loc_( loc
), variable_( variable
), fieldID_( fieldID
)
464 Ast::MemberReferenceFunction::~MemberReferenceFunction( )
471 Ast::MemberReferenceFunction::push_exprs( Ast::ArgListExprs
* args
) const
473 args
->orderedExprs_
->push_back( variable_
);
477 Ast::MemberReferenceFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
479 /* The variable is analyzed as part of the arguments passed to this function, so nothing needs to be done here...
480 * unless we would be able to figure out the type of the argument, and then check if the field reference is valid.
485 Ast::MemberReferenceFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
487 Kernel::ContRef cont
= evalState
->cont_
;
488 RefCountPtr
< const Lang::Value
> arg
= args
.getValue( 0 );
489 cont
->takeHandle( arg
->getField( fieldID_
, arg
),
495 Ast::MutatorReference::MutatorReference( const Ast::SourceLocation
& mutatorLoc
, Ast::StateReference
* state
, const char * mutatorID
)
496 : Ast::Expression( mutatorLoc
), mutatorLoc_( mutatorLoc
), state_( state
), mutatorID_( mutatorID
)
499 Ast::MutatorReference::~MutatorReference( )
501 /* At the time of implementing this bug-fix, state_ will allways be owned by the Ast::CallExpr that is also the owner of us.
502 * Hence, we do not consider ourselves owners. Perhaps one should have a flag indicating whether ownership is transferred
503 * when calling the constructor, but at the moment this seems like a waste of resources.
510 Ast::MutatorReference::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
512 state_
->analyze( this, env
, freeStatesDst
);
513 /* If the type of the state was known here, we should verify that there is a mutator corresponding to the message <mutatorID>.
518 Ast::MutatorReference::eval( Kernel::EvalState
* evalState
) const
520 Kernel::ContRef cont
= evalState
->cont_
;
521 cont
->takeValue( state_
->getHandle( evalState
->env_
, evalState
->dyn_
)->getMutator( mutatorID_
),
527 Ast::SpecialLength::SpecialLength( const Ast::SourceLocation
& loc
, double val
, int sort
)
528 : Ast::Expression( loc
), val_( val
), sort_( sort
)
531 Ast::SpecialLength::~SpecialLength( )
535 Ast::SpecialLength::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
541 Ast::SpecialLength::eval( Kernel::EvalState
* evalState
) const
547 evalState
->dyn_
->specialUnitService( & d
, & a0
, & a1
);
549 if( sort_
== Computation::SPECIALU_NOINFLEX
)
551 Kernel::ContRef cont
= evalState
->cont_
;
552 cont
->takeValue( Kernel::ValueRef( new Lang::Length( val_
* d
* Computation::specialUnitNoInflexion( a0
, a1
) ) ),
556 if( ! sort_
& Computation::SPECIALU_DIST
)
558 throw Exceptions::InternalError( strrefdup( "The special unit is neither based on inflexion or distance" ) );
563 if( sort_
& Computation::SPECIALU_CIRC
)
565 res
*= Computation::specialUnitCircleHandle( a0
);
568 if( sort_
& Computation::SPECIALU_CORR
)
570 res
*= Computation::specialUnitCorrection( a0
, a1
);
573 if( sort_
& Computation::SPECIALU_NOINFLEX
)
575 res
= min( res
, Computation::specialUnitNoInflexion( a0
, a1
) );
577 Kernel::ContRef cont
= evalState
->cont_
;
578 cont
->takeValue( Kernel::ValueRef( new Lang::Length( val_
* d
* res
) ),
583 Ast::DynamicVariable::DynamicVariable( const Ast::SourceLocation
& loc
, const char * id
)
584 : Ast::Expression( loc
), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
589 Ast::DynamicVariable::~DynamicVariable( )
596 delete idKey_
; // This can be done only as long as this is not shared!
600 Ast::DynamicVariable::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
604 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( loc_
, id_
) );
609 Ast::DynamicVariable::eval( Kernel::EvalState
* evalState
) const
611 const Kernel::DynamicVariableProperties
& dynProps
= evalState
->env_
->lookupDynamicVariable( **idKey_
);
613 Kernel::VariableHandle res
= dynProps
.fetch( evalState
->dyn_
);
615 /* Now, we know that if the value was bound to a dynamic expression, a value was bound, and that value has
618 if( ! res
->isThunk( ) )
622 typedef const Lang::DynamicExpression DynType
;
623 RefCountPtr
< DynType
> dynVal
= res
->tryVal
< DynType
>( );
624 dynVal
->evalHelper( evalState
);
627 catch( const NonLocalExit::NotThisType
& ball
)
633 Kernel::ContRef cont
= evalState
->cont_
;
634 cont
->takeHandle( res
,
639 Kernel::DynamicBindingContinuation::DynamicBindingContinuation( const Ast::SourceLocation
& traceLoc
, const Kernel::PassedEnv
& env
, const Kernel::Environment::LexicalKey
& key
, const Ast::DynamicBindingExpression
* bindingExpr
, const Kernel::ContRef
& cont
)
640 : Kernel::Continuation( traceLoc
), env_( env
), key_( key
), bindingExpr_( bindingExpr
), cont_( cont
)
643 Kernel::DynamicBindingContinuation::~DynamicBindingContinuation( )
647 Kernel::DynamicBindingContinuation::takeHandle( Kernel::VariableHandle val
, Kernel::EvalState
* evalState
, bool dummy
) const
649 if( val
->isThunk( ) )
651 val
->force( val
, evalState
);
654 evalState
->cont_
= cont_
;
655 env_
->lookupDynamicVariable( key_
).makeBinding( val
, bindingExpr_
, evalState
);
659 Kernel::DynamicBindingContinuation::up( ) const
664 RefCountPtr
< const char >
665 Kernel::DynamicBindingContinuation::description( ) const
667 return strrefdup( "dynamic binding" );
671 Kernel::DynamicBindingContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
673 env_
->gcMark( marked
);
674 cont_
->gcMark( marked
);
677 Ast::DynamicBindingExpression::DynamicBindingExpression( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, Kernel::Environment::LexicalKey
** idKey
)
678 : Ast::Expression( Ast::SourceLocation( idLoc
, expr
->loc( ) ) ), idLoc_( idLoc
), id_( id
), expr_( expr
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
681 Ast::DynamicBindingExpression::~DynamicBindingExpression( )
690 // Don't delete idKey as it's shared!
694 Ast::DynamicBindingExpression::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
696 expr_
->analyze( this, env
, freeStatesDst
);
699 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( idLoc_
, id_
) );
704 Ast::DynamicBindingExpression::eval( Kernel::EvalState
* evalState
) const
706 const Kernel::DynamicVariableProperties
& dynProps
= evalState
->env_
->lookupDynamicVariable( **idKey_
);
708 if( dynProps
.forceValue( ) || expr_
->immediate_
)
710 evalState
->expr_
= expr_
;
711 evalState
->cont_
= Kernel::ContRef( new Kernel::DynamicBindingContinuation( expr_
->loc( ), evalState
->env_
, **idKey_
, this, evalState
->cont_
) );
715 dynProps
.makeBinding( Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( evalState
->env_
, evalState
->dyn_
, expr_
) ) ),
722 Ast::DynamicStateBindingExpression::DynamicStateBindingExpression( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& dstLoc
, const char * dstId
, Ast::StateReference
* src
)
723 : Ast::Expression( loc
), dstLoc_( dstLoc
), dstId_( dstId
), dstIdKey_( new Kernel::Environment::LexicalKey
* ( 0 ) ), src_( src
)
726 Ast::DynamicStateBindingExpression::~DynamicStateBindingExpression( )
729 if( *dstIdKey_
!= 0 )
733 delete dstIdKey_
; // This can be done only as long as this is not shared!
737 Ast::DynamicStateBindingExpression::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
739 if( *dstIdKey_
== 0 )
741 *dstIdKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalDynamicKey( dstLoc_
, dstId_
) );
746 Ast::DynamicStateBindingExpression::eval( Kernel::EvalState
* evalState
) const
748 const Kernel::DynamicStateProperties
& dstDynProps
= evalState
->env_
->lookupDynamicState( **dstIdKey_
);
750 dstDynProps
.makeBinding( src_
->getHandle( evalState
->env_
, evalState
->dyn_
), this, evalState
);
754 Kernel::WithDynamicContinuation::WithDynamicContinuation( const Ast::SourceLocation
& traceLoc
, Ast::Expression
* expr
, const Kernel::EvalState
& evalState
)
755 : Kernel::Continuation( traceLoc
), expr_( expr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
758 Kernel::WithDynamicContinuation::~WithDynamicContinuation( )
762 Kernel::WithDynamicContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
764 evalState
->dyn_
= Kernel::PassedDyn( new Kernel::DynamicEnvironment( dyn_
, *Helpers::down_cast
< const Lang::DynamicBindings
>( val
, traceLoc_
) ) );
765 evalState
->env_
= env_
;
766 evalState
->expr_
= expr_
;
767 evalState
->cont_
= cont_
;
771 Kernel::WithDynamicContinuation::up( ) const
776 RefCountPtr
< const char >
777 Kernel::WithDynamicContinuation::description( ) const
779 return strrefdup("with dynamic bindings" );
783 Kernel::WithDynamicContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
785 env_
->gcMark( marked
);
786 dyn_
->gcMark( marked
);
787 cont_
->gcMark( marked
);
791 Ast::WithDynamicExpr::WithDynamicExpr( const Ast::SourceLocation
& loc
, Ast::Expression
* bindings
, Ast::Expression
* expr
)
792 : Ast::Expression( loc
), bindings_( bindings
), expr_( expr
)
795 Ast::WithDynamicExpr::~WithDynamicExpr( )
799 Ast::WithDynamicExpr::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
801 bindings_
->analyze( this, env
, freeStatesDst
);
802 expr_
->analyze( this, env
, freeStatesDst
);
806 Ast::WithDynamicExpr::eval( Kernel::EvalState
* evalState
) const
808 evalState
->expr_
= bindings_
;
809 evalState
->cont_
= Kernel::ContRef( new Kernel::WithDynamicContinuation( bindings_
->loc( ), expr_
, *evalState
) );
813 Ast::DynamicVariableDecl::DynamicVariableDecl( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* filterExpr
, Ast::Expression
* defaultExpr
)
814 : Ast::BindNode( loc
, idLoc
, id
), idPos_( new size_t * ( 0 ) )
816 /* This type of expression is an Ast::BindNode so that it is easy to recognize and extract the identifier for static analysis
819 * The expression is implemented as a function call, since there are two subexpressions that may need evaluation.
822 Ast::ArgListExprs
* args
= new Ast::ArgListExprs( false );
823 Ast::DynamicVariableDeclFunction
* res
= new Ast::DynamicVariableDeclFunction( id
, filterExpr
, defaultExpr
, idPos_
);
824 res
->push_exprs( args
);
825 impl_
= new Ast::CallExpr( loc
,
826 RefCountPtr
< const Lang::Function
>( res
),
830 Ast::DynamicVariableDecl::~DynamicVariableDecl( )
834 Ast::DynamicVariableDecl::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
836 impl_
->analyze( this, env
, freeStatesDst
);
839 *idPos_
= new size_t( env
->findLocalDynamicPosition( idLoc_
, id_
) );
844 Ast::DynamicVariableDecl::evalHelper( Kernel::EvalState
* evalState
) const
846 evalState
->expr_
= impl_
;
850 Ast::DynamicVariableDeclFunction::DynamicVariableDeclFunction( const char * id
, Ast::Expression
* filterExpr
, Ast::Expression
* defaultExpr
, size_t ** idPos
)
851 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< dynamic variable declaration >" ) ) ), id_( id
), filterExpr_( filterExpr
), defaultExpr_( defaultExpr
), idPos_( idPos
)
853 formals_
->appendEvaluatedCoreFormal( "filter", Kernel::THE_SLOT_VARIABLE
, true );
854 formals_
->appendEvaluatedCoreFormal( "default", Kernel::THE_SLOT_VARIABLE
, false );
857 Ast::DynamicVariableDeclFunction::~DynamicVariableDeclFunction( )
864 Ast::DynamicVariableDeclFunction::push_exprs( Ast::ArgListExprs
* args
) const
866 args
->orderedExprs_
->push_back( filterExpr_
);
867 args
->orderedExprs_
->push_back( defaultExpr_
);
871 Ast::DynamicVariableDeclFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
873 /* The analysis is carried out by the DynamicVariableDecl expression.
878 Ast::DynamicVariableDeclFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
880 static const char * title
= "< dynamic variable declaration >";
881 typedef const Lang::Function FilterType
;
882 evalState
->env_
->defineDynamic( id_
,
884 Helpers::down_cast_CoreArgument
< FilterType
>( title
, args
, 0, callLoc
),
885 args
.getHandle( 1 ) );
887 Kernel::ContRef cont
= evalState
->cont_
;
888 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
892 Kernel::DynamicVariableDeclContinuation::DynamicVariableDeclContinuation( const Ast::SourceLocation
& traceLoc
, const Ast::DynamicVariableDecl
* declExpr
, Kernel::EvalState
& evalState
)
893 : Kernel::Continuation( traceLoc
), declExpr_( declExpr
), env_( evalState
.env_
), dyn_( evalState
.dyn_
), cont_( evalState
.cont_
)
896 Kernel::DynamicVariableDeclContinuation::~DynamicVariableDeclContinuation( )
900 Kernel::DynamicVariableDeclContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
902 evalState
->env_
= env_
;
903 evalState
->dyn_
= dyn_
;
904 evalState
->cont_
= cont_
;
905 throw Exceptions::NotImplemented( "Deprecated: DynamicVariableDeclContinuation" );
906 // declExpr_->callBack( Helpers::down_cast< const Lang::Function >( val, traceLoc_ ),
911 Kernel::DynamicVariableDeclContinuation::up( ) const
916 RefCountPtr
< const char >
917 Kernel::DynamicVariableDeclContinuation::description( ) const
919 return strrefdup( "dynamic variable declaration" );
923 Kernel::DynamicVariableDeclContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
925 env_
->gcMark( marked
);
926 dyn_
->gcMark( marked
);
927 cont_
->gcMark( marked
);
931 Ast::DynamicStateDecl::DynamicStateDecl( const Ast::SourceLocation
& loc
, const Ast::SourceLocation
& idLoc
, const char * id
, Ast::StateReference
* defaultState
, size_t ** idPos
)
932 : Ast::BindNode( loc
, idLoc
, id
), idPos_( idPos
), defaultState_( defaultState
)
935 Ast::DynamicStateDecl::~DynamicStateDecl( )
940 Ast::DynamicStateDecl::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
944 *idPos_
= new size_t( env
->findLocalDynamicStatePosition( idLoc_
, id_
) );
949 Ast::DynamicStateDecl::evalHelper( Kernel::EvalState
* evalState
) const
951 evalState
->env_
->defineDynamicState( id_
,
956 Kernel::ContRef cont
= evalState
->cont_
;
957 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
,
962 Ast::EvalSymbolFunction::EvalSymbolFunction( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
963 : Lang::Function( new Kernel::EvaluatedFormals( Ast::FileID::build_internal( "< symbol evaluation >" ), true ) ), loc_( loc
), expr_( expr
)
966 Ast::EvalSymbolFunction::~EvalSymbolFunction( )
972 Ast::EvalSymbolFunction::push_exprs( Ast::ArgListExprs
* args
) const
974 args
->orderedExprs_
->push_back( expr_
);
978 Ast::EvalSymbolFunction::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
982 /* expr_ shall be analyzed from the calling expression.
983 * Here, it is only used to locate errors.
988 Ast::EvalSymbolFunction::call( Kernel::EvalState
* evalState
, Kernel::Arguments
& args
, const Ast::SourceLocation
& callLoc
) const
990 RefCountPtr
< const Lang::Value
> untypedVal
= args
.getValue( 0 );
991 typedef const Lang::Symbol ArgType
;
992 ArgType
* val
= dynamic_cast< ArgType
* >( untypedVal
.getPtr( ) );
995 throw Exceptions::TypeMismatch( expr_
->loc( ), untypedVal
->getTypeName( ), ArgType::staticTypeName( ) );
997 if( val
->isUnique( ) )
999 throw Exceptions::OutOfRange( expr_
->loc( ), strrefdup( "Unique symbols can't denote variables." ) );
1003 Kernel::Environment::LexicalKey key
= analysisEnv_
->findLexicalVariableKey( loc_
, val
->name( ).getPtr( ) );
1005 Kernel::PassedEnv env
= evalState
->env_
;
1006 env
->lookup( key
, evalState
);
1010 Ast::DefineVariable::DefineVariable( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, size_t ** idPos
)
1011 : Ast::BindNode( Ast::SourceLocation( idLoc
, expr
->loc( ) ), idLoc
, id
), expr_( expr
), idPos_( idPos
)
1014 Ast::DefineVariable::~DefineVariable( )
1018 /* idPos_ is shared and will be a memory leak which must not be deleted.
1019 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1024 Ast::DefineVariable::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1026 Ast::StateIDSet freeStates
;
1027 expr_
->analyze( this, env
, & freeStates
);
1028 if( ! freeStates
.empty( ) )
1030 expr_
->immediate_
= true;
1031 for( Ast::StateIDSet::const_iterator i
= freeStates
.begin( ); i
!= freeStates
.end( ); ++i
)
1033 freeStatesDst
->insert( *i
);
1038 *idPos_
= new size_t( env
->findLocalVariablePosition( idLoc_
, id_
) );
1043 Ast::DefineVariable::evalHelper( Kernel::EvalState
* evalState
) const
1045 if( expr_
->immediate_
)
1047 evalState
->cont_
= Kernel::ContRef( new Kernel::DefineVariableContinuation( evalState
->env_
,
1051 evalState
->expr_
= expr_
;
1055 evalState
->env_
->define( **idPos_
,
1056 Kernel::VariableHandle( new Kernel::Variable( new Kernel::Thunk( evalState
->env_
,
1059 Kernel::ContRef cont
= evalState
->cont_
;
1060 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
1064 Ast::LexicalVariableLocationExpr::LexicalVariableLocationExpr( const Ast::SourceLocation
& idLoc
, const char * id
, Kind kind
)
1065 : Ast::Expression( idLoc
), id_( id
), kind_( kind
), value_( NullPtr
< const Lang::Value
>( ) )
1070 Ast::LexicalVariableLocationExpr::~LexicalVariableLocationExpr( )
1074 Ast::LexicalVariableLocationExpr::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1076 Kernel::Environment::LexicalKey key
= Kernel::Environment::LexicalKey( env
->findLexicalVariableKey( loc_
, id_
) );
1080 value_
= Kernel::ValueRef( new Lang::Integer( key
.pos_
) );
1083 value_
= Kernel::ValueRef( new Lang::Integer( key
.up_
) );
1089 Ast::LexicalVariableLocationExpr::eval( Kernel::EvalState
* evalState
) const
1091 Kernel::ContRef cont
= evalState
->cont_
;
1092 cont
->takeValue( value_
, evalState
);
1096 Ast::LexicalVariableNameExpr::LexicalVariableNameExpr( const Ast::SourceLocation
& loc
)
1097 : Ast::Expression( loc
), value_( NullPtr
< const Lang::Value
>( ) )
1102 Ast::LexicalVariableNameExpr::~LexicalVariableNameExpr( )
1106 Ast::LexicalVariableNameExpr::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1108 Ast::Node
* n
= parent
->parent( );
1111 Ast::BindNode
* bn
= dynamic_cast< Ast::DefineVariable
* >( n
);
1114 value_
= Kernel::ValueRef( new Lang::String( bn
->id( ), true ) );
1119 Ast::theAnalysisErrorsList
.push_back( new Exceptions::MiscellaneousStaticInconsistency( loc( ), strrefdup( "Cannot retrieve variable name, since the location is not inside a binding's right hand side." ) ) );
1123 Ast::LexicalVariableNameExpr::eval( Kernel::EvalState
* evalState
) const
1125 Kernel::ContRef cont
= evalState
->cont_
;
1126 cont
->takeValue( value_
, evalState
);
1130 Kernel::AssertStructureContinuation::AssertStructureContinuation( const Kernel::ContRef
& cont
, const Ast::SourceLocation
& traceLoc
)
1131 : Kernel::Continuation( traceLoc
), cont_( cont
)
1134 Kernel::AssertStructureContinuation::~AssertStructureContinuation( )
1138 Kernel::AssertStructureContinuation::takeValue( const RefCountPtr
< const Lang::Value
> & val
, Kernel::EvalState
* evalState
, bool dummy
) const
1140 evalState
->cont_
= cont_
;
1141 cont_
->takeValue( Helpers::down_cast_ContinuationArgument
< const Lang::Structure
>( val
, this ), evalState
);
1145 Kernel::AssertStructureContinuation::up( ) const
1150 RefCountPtr
< const char >
1151 Kernel::AssertStructureContinuation::description( ) const
1153 return strrefdup( "Assert type is struct" );
1157 Kernel::AssertStructureContinuation::gcMark( Kernel::GCMarkedSet
& marked
)
1159 cont_
->gcMark( marked
);
1163 Ast::StructSplitReference::StructSplitReference( Ast::SourceLocation fieldLoc
, const char * fieldId
, Ast::Expression
* defaultExpr
)
1164 : Ast::Expression( fieldLoc
),
1165 structLoc_( Ast::THE_UNKNOWN_LOCATION
), // This is a dummy value! The correct value is set later.
1166 fieldId_( fieldId
),
1167 defaultExpr_( defaultExpr
)
1170 Ast::StructSplitReference::StructSplitReference( Ast::SourceLocation fieldLoc
, size_t fieldPos
, Ast::Expression
* defaultExpr
)
1171 : Ast::Expression( fieldLoc
),
1172 structLoc_( Ast::THE_UNKNOWN_LOCATION
), // This is a dummy value! The correct value is set later.
1173 fieldId_( 0 ), fieldPos_( fieldPos
),
1174 defaultExpr_( defaultExpr
)
1177 Ast::StructSplitReference::~StructSplitReference( )
1183 if( defaultExpr_
!= 0 )
1185 delete defaultExpr_
;
1190 Ast::StructSplitReference::setStruct( Ast::SourceLocation structLoc
, size_t ** structPos
)
1192 structLoc_
= structLoc
;
1193 structPos_
= structPos
;
1197 Ast::StructSplitReference::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1199 if( defaultExpr_
!= 0 )
1201 defaultExpr_
->analyze( this, env
, freeStatesDst
);
1206 Ast::StructSplitReference::eval( Kernel::EvalState
* evalState
) const
1208 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1209 typedef const Lang::Structure StructType
;
1210 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1212 Kernel::ContRef cont
= evalState
->cont_
;
1217 cont
->takeHandle( structVal
->getField( fieldId_
, structVal
),
1221 catch( const Exceptions::NonExistentMember
& ball
)
1223 if( defaultExpr_
== 0 )
1227 // Never mind, we use the default instead. See below.
1234 cont
->takeHandle( structVal
->getPosition( fieldPos_
, structVal
),
1238 catch( const Exceptions::NonExistentPosition
& ball
)
1240 if( defaultExpr_
== 0 )
1244 // Never mind, we use the default instead. See below.
1248 if( defaultExpr_
== 0 )
1250 throw Exceptions::InternalError( "Just about to use null pointer defaultExpr_ in StructSplitReference::eval." );
1252 evalState
->expr_
= defaultExpr_
;
1255 Ast::StructSplitSink::StructSplitSink( )
1256 : Ast::Expression( Ast::THE_UNKNOWN_LOCATION
), structLoc_( Ast::THE_UNKNOWN_LOCATION
)
1259 Ast::StructSplitSink::~StructSplitSink( )
1263 Ast::StructSplitSink::setStruct( Ast::SourceLocation structLoc
, size_t ** structPos
, size_t consumedArguments
)
1265 structLoc_
= structLoc
;
1266 structPos_
= structPos
;
1267 consumedArguments_
= consumedArguments
;
1271 Ast::StructSplitSink::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1273 /* Nothing to do! */
1277 Ast::StructSplitSink::eval( Kernel::EvalState
* evalState
) const
1279 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1280 typedef const Lang::Structure StructType
;
1281 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1283 Kernel::ContRef cont
= evalState
->cont_
;
1284 cont
->takeValue( structVal
->getSink( consumedArguments_
),
1289 Ast::AssertNoSinkNeeded::AssertNoSinkNeeded( const Ast::SourceLocation
& loc
, size_t orderedCount
, Ast::SourceLocation structLoc
, size_t ** structPos
)
1290 : Ast::Assertion( loc
), orderedCount_( orderedCount
), structLoc_( structLoc
), structPos_( structPos
)
1293 Ast::AssertNoSinkNeeded::~AssertNoSinkNeeded( )
1297 Ast::AssertNoSinkNeeded::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1299 /* immediate_ is already true by the inheritage from Ast::Assertion. */
1303 Ast::AssertNoSinkNeeded::eval( Kernel::EvalState
* evalState
) const
1305 Kernel::VariableHandle structHandle
= evalState
->env_
->getVarHandle( **structPos_
);
1306 typedef const Lang::Structure StructType
;
1307 RefCountPtr
< StructType
> structVal
= structHandle
->getVal
< StructType
>( "Type-checked value in StructSplitReference::eval." );
1309 if( structVal
->argList_
->orderedExprs_
->size( ) > orderedCount_
)
1311 throw Exceptions::SinkRequired( loc_
, orderedCount_
, structVal
->argList_
->orderedExprs_
->size( ) );
1314 Kernel::ContRef cont
= evalState
->cont_
;
1315 cont
->takeHandle( Kernel::THE_VOID_VARIABLE
, evalState
);
1318 size_t Ast::SplitDefineVariables::splitVarCount
= 0;
1319 PtrOwner_back_Access
< std::list
< const char * > > Ast::SplitDefineVariables::mem
;
1321 Ast::SplitDefineVariables::SplitDefineVariables( )
1322 : sinkDefine_( 0 ), sinkExpr_( 0 ), seenNamed_( false ), seenDefault_( false )
1324 std::ostringstream oss
;
1325 oss
<< Kernel::SPLIT_VAR_PREFIX
<< splitVarCount
;
1326 splitVarId_
= strdup( oss
.str( ).c_str( ) );
1327 mem
.push_back( splitVarId_
);
1332 Ast::SplitDefineVariables::newSplitVarId( ) const
1334 return strdup( splitVarId_
);
1338 Ast::StateReference::StateReference( const Ast::SourceLocation
& loc
)
1342 Ast::StateReference::~StateReference( )
1346 Ast::LexiographicState::LexiographicState( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
1347 : Ast::StateReference( loc
), id_( id
), idKey_( idKey
)
1350 Ast::LexiographicState::~LexiographicState( )
1357 delete idKey_
; // This can be done only as long as this is not shared!
1361 Ast::LexiographicState::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1363 /* The following lines is the ugly solution to the problem that the inherited parent_ and analysisEnv_
1364 * are not well defined for reused nodes. And nodes of this type are typically reused.
1365 * For this type of node, one _could_ refer to someParent_ and someAnalysisEnv_ instead, but probably,
1366 * it is a mistake to even try.
1368 someParent_
= parent_
;
1370 someAnalysisEnv_
= analysisEnv_
;
1375 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalStateKey( loc_
, id_
) );
1377 if( ! (*idKey_
)->isMissing( ) )
1379 freeStatesDst
->insert( env
->getStateID( **idKey_
) );
1384 Ast::LexiographicState::getHandle( Kernel::PassedEnv env
, Kernel::PassedDyn dyn
) const
1386 return env
->getStateHandle( **idKey_
);
1390 Ast::DynamicState::DynamicState( const Ast::SourceLocation
& loc
, const char * id
)
1391 : Ast::StateReference( loc
), id_( id
), idKey_( new Kernel::Environment::LexicalKey
* ( 0 ) )
1394 Ast::DynamicState::~DynamicState( )
1401 delete idKey_
; // This can be done only as long as this is not shared!
1405 Ast::DynamicState::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1407 /* See comment in LexicalState::analyze_impl.
1409 someParent_
= parent_
;
1411 someAnalysisEnv_
= analysisEnv_
;
1414 /* It would make sense to check the reference and...
1415 * This might be overly conservative... but we really shouldn't support dynamic states anyway.
1417 freeStatesDst
->insert( Ast::AnalysisEnvironment::getTheAnyStateID( ) );
1421 Ast::DynamicState::getHandle( Kernel::PassedEnv env
, Kernel::PassedDyn dyn
) const
1423 throw Exceptions::NotImplemented( "Referencing dynamic states" );
1427 Ast::IntroduceState::IntroduceState( const Ast::SourceLocation
& idLoc
, const char * id
, Ast::Expression
* expr
, size_t ** idPos
)
1428 : Ast::BindNode( Ast::SourceLocation( idLoc
, expr
->loc( ) ), idLoc
, id
), expr_( expr
), idPos_( idPos
)
1431 Ast::IntroduceState::~IntroduceState( )
1435 /* idPos_ shared and will be a memory leak which must not be deleted.
1436 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1442 Ast::IntroduceState::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1444 expr_
->analyze( this, env
, freeStatesDst
);
1448 *idPos_
= new size_t( env
->findLocalStatePosition( idLoc_
, id_
) );
1451 stateID_
= env
->getStateID( **idPos_
);
1452 freeStatesDst
->insert( stateID_
);
1456 Ast::IntroduceState::evalHelper( Kernel::EvalState
* evalState
) const
1458 evalState
->cont_
= Kernel::ContRef( new Kernel::IntroduceStateContinuation( evalState
->env_
,
1462 evalState
->expr_
= expr_
;
1466 Ast::Insertion::Insertion( Ast::StateReference
* stateRef
, Ast::Expression
* expr
)
1467 : Ast::Expression( Ast::SourceLocation( stateRef
->loc( ), expr
->loc( ) ) ), stateRef_( stateRef
), expr_( expr
)
1470 Ast::Insertion::~Insertion( )
1474 Ast::Insertion::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1476 stateRef_
->analyze( this, env
, freeStatesDst
); /* This will always add something to the set of free states. */
1477 expr_
->analyze( this, env
, freeStatesDst
);
1481 Ast::Insertion::eval( Kernel::EvalState
* evalState
) const
1483 evalState
->cont_
= Kernel::ContRef( new Kernel::InsertionContinuation( stateRef_
->getHandle( evalState
->env_
, evalState
->dyn_
),
1487 evalState
->expr_
= expr_
;
1490 Ast::Freeze::Freeze( const Ast::SourceLocation
& idLoc
, const char * id
, size_t ** idPos
)
1491 : Ast::Expression( idLoc
), id_( id
), idPos_( idPos
)
1496 Ast::Freeze::~Freeze( )
1498 /* idPos shared and will be a memory leak which must not be deleted.
1499 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1504 Ast::Freeze::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1508 *idPos_
= new size_t( env
->findLocalStatePosition( loc( ), id_
) );
1511 freeStatesDst
->insert( env
->getStateID( **idPos_
) );
1515 Ast::Freeze::eval( Kernel::EvalState
* evalState
) const
1517 evalState
->env_
->freeze( **idPos_
, evalState
, loc( ) );
1521 Ast::Peek::Peek( const Ast::SourceLocation
& idLoc
, Ast::StateReference
* stateRef
)
1522 : Ast::Expression( idLoc
), stateRef_( stateRef
)
1529 /* idPos shared and will be a memory leak which must not be deleted.
1530 * It would be easy to fix the leak using RefCountPtr< size_t >, but the leakage is constant space, so silly efficiency is prioritized.
1535 Ast::Peek::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1537 stateRef_
->analyze( this, env
, freeStatesDst
); /* This will always add something to the set of free states. */
1541 Ast::Peek::eval( Kernel::EvalState
* evalState
) const
1543 stateRef_
->getHandle( evalState
->env_
, evalState
->dyn_
)->peek( evalState
, loc( ) );
1547 Ast::DynamicExpression::DynamicExpression( const Ast::SourceLocation
& loc
, Ast::Expression
* expr
)
1548 : Ast::Expression( loc
), expr_( expr
)
1553 Ast::DynamicExpression::~DynamicExpression( )
1557 Ast::DynamicExpression::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1559 Ast::StateIDSet
* freeStates
= new Ast::StateIDSet
;
1560 expr_
->analyze( this, env
, freeStates
);
1562 if( ! freeStates
->empty( ) )
1564 Ast::theAnalysisErrorsList
.push_back( new Exceptions::IllegalFreeStates( expr_
->loc( ), freeStates
, "dynamic expressions must be pure" ) );
1573 Ast::DynamicExpression::eval( Kernel::EvalState
* evalState
) const
1575 Kernel::ContRef cont
= evalState
->cont_
;
1576 cont
->takeValue( Kernel::ValueRef( new Lang::DynamicExpression( evalState
->env_
, expr_
) ),
1581 Ast::LexiographicType::LexiographicType( const Ast::SourceLocation
& loc
, const char * id
, Kernel::Environment::LexicalKey
** idKey
)
1582 : Ast::Expression( loc
), id_( id
), idKey_( idKey
)
1587 Ast::LexiographicType::~LexiographicType( )
1594 delete idKey_
; // This can be done only as long as this is not shared!
1598 Ast::LexiographicType::analyze_impl( Ast::Node
* parent
, Ast::AnalysisEnvironment
* env
, Ast::StateIDSet
* freeStatesDst
)
1602 *idKey_
= new Kernel::Environment::LexicalKey( env
->findLexicalTypeKey( loc_
, id_
) );
1607 Ast::LexiographicType::eval( Kernel::EvalState
* evalState
) const
1609 evalState
->env_
->lookup( **idKey_
, evalState
);