New source code reflection: absolute_identifier_string
[shapes.git] / source / environment.cc
blobdc3266a9a01a25530325f4dfee8e60942c1497ce
1 /* This file is part of Shapes.
3 * Shapes is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * any later version.
8 * Shapes is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with Shapes. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright 2008, 2013 Henrik Tidefelt
19 #include <cmath>
20 #include <iomanip>
22 #include "environment.h"
23 #include "shapesexceptions.h"
24 #include "shapescore.h"
25 #include "consts.h"
26 #include "globals.h"
27 #include "shapesvalue.h"
28 #include "classtypes.h"
29 #include "hottypes.h"
30 #include "continuations.h"
31 #include "statetypes.h"
32 #include "multipage.h"
33 #include "errorhandlers.h"
34 #include "debuglog.h"
35 #include "check.h"
37 using namespace Shapes;
40 size_t Kernel::Environment::createdCount = 0;
41 size_t Kernel::Environment::liveCount = 0;
42 Kernel::Environment::LexicalKey Kernel::Environment::theMissingKey( 0, std::numeric_limits< size_t >::max( ) );
44 template< class T >
45 class Binary
47 public:
48 T val;
49 Binary( const T & _val ) : val( _val ) { }
52 template< class T >
53 std::ostream &
54 operator << ( std::ostream & os, const Binary< T > & self )
56 for( int i = 8*sizeof( T ) - 1; i >= 0; --i )
58 if( (( self.val & (T(1)<<i) )) != 0 )
60 os << 1 ;
62 else
64 os << '_' ;
67 return os;
72 Kernel::Thunk::Thunk( Kernel::PassedEnv env, Kernel::PassedDyn dyn, Ast::Expression * expr )
73 : env_( env ), dyn_( dyn ), expr_( expr ), forced_( false )
74 { }
76 void
77 Kernel::Thunk::force( Kernel::EvalState * evalState, bool onlyOnce ) const
79 if( onlyOnce )
81 if( forced_ )
83 throw Exceptions::InternalError( "It's unwise to force a thunk twice! It should be deleted right after the first force." );
85 forced_ = true;
88 evalState->expr_ = expr_;
89 evalState->env_ = env_;
90 evalState->dyn_ = dyn_;
92 /* The continuation is not se by the thunk! */
95 Kernel::Thunk *
96 Kernel::Thunk::deepCopy( )
98 return new Thunk( env_, dyn_, expr_ );
102 void
103 Kernel::Thunk::gcMark( Kernel::GCMarkedSet & marked )
105 if( ! forced_ )
107 env_->gcMark( marked );
108 dyn_->gcMark( marked );
112 Ast::Expression *
113 Kernel::Thunk::getExpr( )
115 return expr_;
118 void
119 Kernel::Thunk::printEnv( std::ostream & os ) const
121 env_->print( os );
125 Kernel::Variable::Variable( const RefCountPtr< const Lang::Value > & val )
126 : thunk_( 0 ), val_( val ), state_( Kernel::Variable::COLD )
129 Kernel::Variable::Variable( Kernel::Thunk * thunk )
130 : thunk_( thunk ), val_( NullPtr< const Lang::Value >( ) ), state_( Kernel::Variable::THUNK )
133 Kernel::Variable::~Variable( )
135 if( thunk_ != 0 )
137 delete thunk_;
141 Kernel::State::State( )
142 : alive_( true )
145 Kernel::State::~State( )
148 void
149 Kernel::State::tackOn( Kernel::EvalState * evalState, const RefCountPtr< const Lang::Value > & piece, const Ast::SourceLocation & callLoc )
151 if( ! alive_ )
153 throw Exceptions::DeadStateAccess( );
155 this->tackOnImpl( evalState, piece, callLoc );
158 void
159 Kernel::State::peek( Kernel::EvalState * evalState, const Ast::SourceLocation & callLoc )
161 if( ! alive_ )
163 throw Exceptions::DeadStateAccess( );
165 this->peekImpl( evalState, callLoc );
168 void
169 Kernel::State::freeze( Kernel::EvalState * evalState, const Ast::SourceLocation & callLoc )
171 if( ! alive_ )
173 throw Exceptions::DeadStateAccess( );
175 /* It would make sense to have an intermediate state here.
177 alive_ = false;
179 // Perhaps, it would be smart to use a continuation to erase the implementation once it is used...
180 // evalState->cont_ = Kernel::ContRef( new Kernel::StmtStoreVariableContinuation( selfRef, evalState->cont_, callLoc ) );
182 this->freezeImpl( evalState, callLoc );
185 RefCountPtr< const Lang::Function >
186 Kernel::State::getMutator( const char * mutatorID )
188 return getClass( )->getMutator( mutatorID );
191 RefCountPtr< const char >
192 Kernel::State::getTypeName( ) const
194 return this->getClass( )->getPrettyName( );
197 bool
198 Kernel::State::isAlive( ) const
200 return alive_;
204 void
205 Kernel::Variable::force( const Kernel::VariableHandle & selfRef, Kernel::EvalState * evalState ) const
207 /* The reason that selfRef is passed as const reference is that this is a const method, and it is expected that selfRef actually is a handle to *this. Hence, it does not make sense to not allow the selfRef to be passed by const reference. On the other hand, we actually do need to do some non-const things with selfRef, and therefore we resort to some ugly const_casting this time.
209 if( state_ == Kernel::Variable::THUNK )
211 state_ = Kernel::Variable::FORCING;
212 evalState->cont_ = Kernel::ContRef( new Kernel::StoreVariableContinuation( const_cast< Kernel::VariableHandle & >( selfRef ), evalState->cont_, thunk_->getExpr( )->loc( ) ) );
213 thunk_->force( evalState );
214 delete thunk_;
215 thunk_ = 0;
216 return;
218 if( val_ == NullPtr< const Lang::Value >( ) )
220 if( state_ == Kernel::Variable::FORCING )
222 throw Exceptions::MiscellaneousRequirement( "Cyclic forcing." );
224 throw Exceptions::InternalError( "Force failed. No value, not forcing." );
226 Kernel::ContRef cont = evalState->cont_;
227 cont->takeHandle( const_cast< Kernel::VariableHandle & >( selfRef ), evalState );
230 RefCountPtr< const Lang::Value > &
231 Kernel::Variable::getUntyped( ) const
233 if( val_ == NullPtr< const Lang::Value >( ) )
235 throw Exceptions::InternalError( "The value is not ready to be get without continuation." );
237 return val_;
241 bool
242 Kernel::Variable::isThunk( ) const
244 return ( state_ & Kernel::Variable::FORCING ) != 0;
247 Kernel::Thunk *
248 Kernel::Variable::copyThunk( ) const
250 if( thunk_ == 0 )
252 throw Exceptions::InternalError( "Variable::copyThunk: There was no thunk to copy." );
254 return thunk_->deepCopy( );
257 void
258 Kernel::Variable::gcMark( Kernel::GCMarkedSet & marked )
260 if( thunk_ != 0 )
262 thunk_->gcMark( marked );
263 return;
265 if( val_ != NullPtr< const Lang::Value >( ) )
267 const_cast< Lang::Value * >( val_.getPtr( ) )->gcMark( marked );
271 void
272 Kernel::Variable::setValue( const RefCountPtr< const Lang::Value > & val ) const
274 val_ = val;
275 state_ = Kernel::Variable::COLD;
279 Kernel::DynamicVariableProperties::~DynamicVariableProperties( )
281 /* We do not own id_.
285 Kernel::DynamicStateProperties::~DynamicStateProperties( )
287 /* We do not own id_.
292 void
293 Kernel::Environment::initDefineCoreFunction( Lang::CoreFunction * fun )
295 initDefineHandle( fun->getTitle( ), Kernel::VariableHandle( new Kernel::Variable( RefCountPtr< const Lang::Value >( fun ) ) ) );
298 void
299 Kernel::Environment::initDefineCoreFunction( RefCountPtr< const Lang::CoreFunction > fun )
301 initDefineHandle( fun->getTitle( ), Kernel::VariableHandle( new Kernel::Variable( fun ) ) );
304 void
305 Kernel::Environment::initDefineHandle( const char * simpleId, const Kernel::VariableHandle & val )
307 Ast::PlacedIdentifier id( Lang::THE_CORE_NAMESPACE_PATH, simpleId );
309 if( Interaction::logGlobals )
311 Kernel::theDebugLog.os( ) << "--log-globals> variable: " << simpleId << std::endl ;
314 if( ! bindings_->insert( id ) )
316 throw Exceptions::IntroducingExisting( Ast::SourceLocation( Ast::FileID::build_internal( "< Initialization >" ) ), id );
318 values_->push_back( val );
320 CHECK( /* Assume that matching element counts insure that the identifier is mapped to the correct position. */
321 if( values_->size( ) != bindings_->size( ) ){
322 throw Exceptions::InternalError( "Kernel::Environment::initDefineHandle: Inconsistent number of values." );
323 } );
326 void
327 Kernel::Environment::initDefine( const char * simpleId, const RefCountPtr< const Lang::Value > & val )
329 initDefineHandle( simpleId, Kernel::VariableHandle( new Kernel::Variable( val ) ) );
332 void
333 Kernel::Environment::initDefine( const char * simpleId, Kernel::StateHandle state )
335 initDefine( Ast::PlacedIdentifier( Lang::THE_CORE_NAMESPACE_PATH, simpleId ), state );
338 void
339 Kernel::Environment::initDefine( const Ast::PlacedIdentifier & id, Kernel::StateHandle state )
341 if( Interaction::logGlobals )
343 std::ostream & os = Kernel::theDebugLog.os( );
344 os << "--log-globals> state: " ;
345 id.show( os, Ast::Identifier::STATE );
346 os << std::endl ;
349 if( ! stateBindings_->insert( id ) )
351 throw Exceptions::IntroducingExisting( Ast::SourceLocation( Ast::FileID::build_internal( "< Initialization >" ) ), id );
353 states_->push_back( state );
355 CHECK( /* Assume that matching element counts insure that the identifier is mapped to the correct position. */
356 if( states_->size( ) != stateBindings_->size( ) ){
357 throw Exceptions::InternalError( "Kernel::Environment::initDefine: Inconsistent number of states." );
358 } );
361 void
362 Kernel::Environment::initDefineClass( const RefCountPtr< const Lang::Class > & cls )
364 RefCountPtr< const char > idRef = cls->getPrettyName( );
365 const char * simpleId = strdup( idRef.getPtr( ) );
366 charPtrDeletionList_.push_back( simpleId );
367 initDefineHandle( simpleId, Kernel::VariableHandle( new Kernel::Variable( cls ) ) );
370 void
371 Kernel::Environment::initDefineDynamic( DynamicVariableProperties * dynProps )
373 const Ast::PlacedIdentifier & id( dynProps->id( ) );
375 if( Interaction::logGlobals )
377 Kernel::theDebugLog.os( ) << "--log-globals> dynamic: " ;
378 id.show( Kernel::theDebugLog.os( ), Ast::Identifier::DYNAMIC_VARIABLE );
379 Kernel::theDebugLog.os( ) << std::endl ;
382 if( ! dynamicKeyBindings_->insert( id ) )
384 throw Exceptions::IntroducingExisting( Ast::SourceLocation( Ast::FileID::build_internal( "< System dynamic variable initialization >" ) ), id );
386 dynamicKeyValues_->push_back( dynProps );
388 CHECK( /* Assume that matching element counts insure that the identifier is mapped to the correct position. */
389 if( dynamicKeyValues_->size( ) != dynamicKeyBindings_->size( ) ){
390 throw Exceptions::InternalError( "Kernel::Environment::initDefineDynamic: Inconsistent number of dynamic keys (1 argument)." );
391 } );
394 void
395 Kernel::Environment::initDefineDynamic( const char * simpleId, const RefCountPtr< const Lang::Function > & filter, const Kernel::VariableHandle & defaultVal )
397 initDefineDynamic( newPlacedIdentifier( Lang::THE_CORE_NAMESPACE_PATH, simpleId ), filter, defaultVal );
400 void
401 Kernel::Environment::initDefineDynamic( const Ast::PlacedIdentifier * id, const RefCountPtr< const Lang::Function > & filter, const Kernel::VariableHandle & defaultVal )
403 if( ! dynamicKeyBindings_->insert( *id ) )
405 throw Exceptions::IntroducingExisting( Ast::SourceLocation( Ast::FileID::build_internal( "< System dynamic variable initialization >" ) ), *id );
407 Kernel::DynamicEnvironmentKeyType key = dynamicKeyValues_->size( );
408 dynamicKeyValues_->push_back( new Kernel::UserDynamicVariableProperties( id, key, filter, defaultVal ) );
410 CHECK( /* Assume that matching element counts insure that the identifier is mapped to the correct position. */
411 if( dynamicKeyValues_->size( ) != dynamicKeyBindings_->size( ) ){
412 throw Exceptions::InternalError( "Kernel::Environment::initDefineDynamic: Inconsistent number of dynamic keys (3 arguments)." );
413 } );
416 void
417 Kernel::Environment::initDefineDynamicHandler( const Ast::PlacedIdentifier & id, const char * msg )
419 initDefineDynamic( id.clone( ),
420 Lang::THE_IDENTITY,
421 Helpers::newValHandle( new Lang::ExceptionWrapper< Exceptions::HandlerError >( id, msg ) ) );
424 PtrOwner_back_Access< std::list< const Ast::PlacedIdentifier * > > Kernel::Environment::coreIdentifiers;
426 const Ast::PlacedIdentifier *
427 Kernel::Environment::newPlacedIdentifier( const RefCountPtr< const Ast::NamespacePath > & path, const char * simpleId )
429 const Ast::PlacedIdentifier * id = new Ast::PlacedIdentifier( path, simpleId );
430 coreIdentifiers.push_back( id );
431 return id;
434 Kernel::Environment::Environment( std::list< Kernel::Environment * > & garbageArea, const char * debugName )
435 : parent_( 0 ),
436 bindings_( new Ast::IdentifierTree ),
437 values_( new std::vector< Kernel::VariableHandle >( ) ),
438 dynamicKeyBindings_( new Ast::IdentifierTree ),
439 dynamicKeyValues_( new std::vector< DynamicVariableProperties * > ),
440 stateBindings_( new Ast::IdentifierTree ),
441 states_( new std::vector< Kernel::StateHandle >( ) ),
442 dynamicStateKeyBindings_( new Ast::IdentifierTree ),
443 dynamicStateKeyValues_( new std::vector< DynamicStateProperties * > ),
444 debugName_( debugName )
446 garbageArea.push_back( this );
447 ++createdCount;
448 ++liveCount;
451 Kernel::Environment::Environment( std::list< Kernel::Environment * > & garbageArea, Environment * parent, Ast::IdentifierTree * bindings, const RefCountPtr< std::vector< VariableHandle > > & values, Ast::IdentifierTree * stateBindings, const RefCountPtr< std::vector< StateHandle > > & states, const char * debugName )
452 : parent_( parent ),
453 bindings_( bindings ), values_( values ), dynamicKeyBindings_( 0 ),
454 stateBindings_( stateBindings ), states_( states ), dynamicStateKeyBindings_( 0 ),
455 debugName_( debugName )
456 //, unitMap_( NullPtr< Kernel::Environment::UnitMapType >( ) )
458 garbageArea.push_back( this );
459 // if( parent_ != 0 )
460 // {
461 // unitMap_ = parent->unitMap_;
462 // }
463 ++createdCount;
464 ++liveCount;
467 Kernel::Environment::~Environment( )
469 clear( );
470 if( dynamicKeyBindings_ != 0 )
472 if( parent_ == 0 )
474 /* The condition means that this is the global evironment, which created its own map.
476 delete dynamicKeyBindings_;
478 /* However, the values will always be owned by the environment itself, and be defined whenever dynamicKeyBindings != 0
480 for( std::vector< DynamicVariableProperties * >::iterator i = dynamicKeyValues_->begin( ); i != dynamicKeyValues_->end( ); ++i )
482 if( *i != 0 )
484 delete *i;
487 delete dynamicKeyValues_;
489 if( stateBindings_ != 0 )
491 if( parent_ == 0 )
493 /* The condition means that this is the global evironment, which created its own map.
495 delete stateBindings_;
497 /* However, the values will always be owned by the environment itself, and be defined whenever dynamicKeyBindings != 0
499 for( std::vector< StateHandle >::iterator i = states_->begin( ); i != states_->end( ); ++i )
501 if( *i != 0 )
503 delete *i;
507 if( dynamicStateKeyBindings_ != 0 )
509 if( parent_ == 0 )
511 /* The condition means that this is the global evironment, which created its own map.
513 delete dynamicStateKeyBindings_;
515 /* However, the values will always be owned by the environment itself, and be defined whenever dynamicKeyBindings != 0
517 for( std::vector< DynamicStateProperties * >::iterator i = dynamicStateKeyValues_->begin( ); i != dynamicStateKeyValues_->end( ); ++i )
519 if( *i != 0 )
521 delete *i;
524 delete dynamicStateKeyValues_;
526 --liveCount;
529 void
530 Kernel::Environment::setParent( Kernel::Environment * parent )
532 parent_ = parent;
533 // unitMap_ = parent.unitMap_;
536 Kernel::Environment *
537 Kernel::Environment::getParent( )
539 if( isBaseEnvironment( ) )
541 throw Exceptions::MiscellaneousRequirement( "Trying to find the parent of the top level environment." );
543 return parent_;
546 const Kernel::Environment *
547 Kernel::Environment::getParent( ) const
549 if( isBaseEnvironment( ) )
551 throw Exceptions::MiscellaneousRequirement( "Trying to find the parent of the top level environment." );
553 return parent_;
556 void
557 Kernel::Environment::setupDynamicKeyVariables( Ast::IdentifierTree * dynamicKeyBindings )
559 if( dynamicKeyBindings_ == 0 )
561 dynamicKeyBindings_ = dynamicKeyBindings;
562 dynamicKeyValues_ = new std::vector< DynamicVariableProperties * >;
564 CHECK(
565 else
567 if( dynamicKeyBindings_ != dynamicKeyBindings )
569 throw Exceptions::InternalError( "Kernel::Environment::setupDynamicKeyVariables: dynamicKeyBindings_ != dynamicKeyBindings" );
573 size_t theSize = dynamicKeyBindings_->size( );
574 dynamicKeyValues_->reserve( theSize );
575 while( dynamicKeyValues_->size( ) < theSize )
577 dynamicKeyValues_->push_back( 0 );
581 void
582 Kernel::Environment::setupDynamicStateKeyVariables( Ast::IdentifierTree * dynamicStateKeyBindings )
584 if( dynamicStateKeyBindings_ == 0 )
586 dynamicStateKeyBindings_ = dynamicStateKeyBindings;
587 dynamicStateKeyValues_ = new std::vector< DynamicStateProperties * >;
589 CHECK(
590 else
592 if( dynamicStateKeyBindings_ != dynamicStateKeyBindings )
594 throw Exceptions::InternalError( "Kernel::Environment::setupDynamicStateKeyVariables: dynamicStateKeyBindings_ != dynamicStateKeyBindings" );
598 size_t theSize = dynamicStateKeyBindings_->size( );
599 dynamicStateKeyValues_->reserve( theSize );
600 while( dynamicStateKeyValues_->size( ) < theSize )
602 dynamicStateKeyValues_->push_back( 0 );
606 void
607 Kernel::Environment::extendVectors( )
609 values_->reserve( bindings_->size( ) );
610 while( values_->size( ) < bindings_->size( ) )
612 values_->push_back( NullPtr< Kernel::Variable >( ) );
615 states_->reserve( stateBindings_->size( ) );
616 while( states_->size( ) < stateBindings_->size( ) )
618 states_->push_back( NullPtr< Kernel::State >( ) );
623 void
624 Kernel::Environment::clear( )
626 /* Strange that this is empty...
627 * The idea, though, is that the reference counting of this->values shall take care of deletion.
631 Ast::AnalysisEnvironment *
632 Kernel::Environment::newAnalysisEnvironment( Ast::AnalysisEnvironment * parent ) const
634 Ast::AnalysisEnvironment * res = new Ast::AnalysisEnvironment( Ast::theAnalysisEnvironmentList, parent, bindings_, stateBindings_ );
635 if( dynamicKeyBindings_ != 0 )
637 res->setupDynamicKeyVariables( dynamicKeyBindings_ );
639 if( dynamicStateKeyBindings_ != 0 )
641 res->setupDynamicStateKeyVariables( dynamicStateKeyBindings_ );
644 return res;
647 void
648 Kernel::Environment::gcMark( Kernel::GCMarkedSet & marked )
650 if( gcMarked_ )
652 return;
654 gcMarked_ = true;
655 marked.insert( marked.begin( ), this );
657 values_->clear( );
660 void
661 Kernel::Environment::collect( std::list< Kernel::Environment * > & garbageArea )
663 for( std::list< Kernel::Environment * >::iterator i = garbageArea.begin( ); i != garbageArea.end( ); ++i )
665 (*i)->clear_gcMarked( );
668 Kernel::GCMarkedSet marked;
669 for( std::list< Kernel::Environment * >::iterator i = garbageArea.begin( ); i != garbageArea.end( ); ++i )
671 (*i)->gcMark( marked );
674 for( std::list< Kernel::Environment * >::iterator i = garbageArea.begin( ); i != garbageArea.end( ); )
676 if( (*i)->gcMarked( ) )
678 ++i;
679 continue;
681 std::list< Kernel::Environment * >::iterator tmp = i;
682 ++i;
683 delete *tmp;
684 garbageArea.erase( tmp );
689 const size_t Ast::IdentifierTree::NOT_FOUND = std::numeric_limits< size_t >::max( );
691 Ast::IdentifierTree::IdentifierTree( )
692 : size_( 0 )
695 Ast::IdentifierTree::~IdentifierTree( )
697 typedef typeof namespaces_ MapType;
698 for( MapType::iterator i = namespaces_.begin( ); i != namespaces_.end( ); ++i )
700 delete i->second;
704 bool
705 Ast::IdentifierTree::insert( const Ast::PlacedIdentifier & id )
707 return insert( id.absolutePath( ).begin( ), id.absolutePath( ).end( ), id.simpleId( ), size_ );
710 bool
711 Ast::IdentifierTree::insert( Ast::NamespacePath::const_iterator begin, const Ast::NamespacePath::const_iterator & end, const char * simpleId, size_t pos )
713 if( begin == end ){
715 typedef typeof simpleIdentifiers_ MapType;
716 if( simpleIdentifiers_.find( simpleId ) != simpleIdentifiers_.end( ) )
717 return false;
718 simpleIdentifiers_.insert( MapType::value_type( simpleId, pos ) );
719 ++size_;
720 return true;
722 }else{
724 typedef typeof namespaces_ MapType;
725 MapType::iterator j = namespaces_.find( *begin );
726 if( j != namespaces_.end( ) ){
728 bool success = j->second->insert( ++begin, end, simpleId, pos );
729 if( success )
730 ++size_;
731 return success;
733 }else{
735 IdentifierTree * tree = new IdentifierTree;
736 namespaces_.insert( MapType::value_type( *begin, tree ) );
737 bool success = tree->insert( ++begin, end, simpleId, pos );
738 CHECK(
739 if( ! success ){
740 throw Exceptions::InternalError( "Ast::IdentifierTree::insert: Could not insert into new namespace." );
743 ++size_;
744 return true;
751 size_t
752 Ast::IdentifierTree::lookup( const Ast::Identifier & id ) const
754 if( id.absolute( ) ){
756 if( ! id.path( ).empty( ) ){
758 const Ast::SearchContext & context = id.searchContext( );
759 Ast::NamespacePath::const_iterator begin = id.path( ).begin( );
760 const char * pathFront = *begin;
761 ++begin;
763 for( RefCountPtr< const Ast::NamespaceAliasStack > i( context.aliasStack( ) ); i != NullPtr< const Ast::NamespaceAliasStack >( ); i = i->cdr( ) ){
764 if( strcmp( pathFront, i->carAlias( ) ) != 0 )
765 continue;
767 if( i->carAbsolute( ) ){
769 return lookupSuffix( i->carOriginal( ).begin( ), i->carOriginal( ).end( ), id );
771 }else{
773 return lookupPrefix( context.lexicalPath( )->begin( ), context.lexicalPath( )->end( ), i->carOriginal( ), id );
779 return lookupSuffix( id.path( ).begin( ), id.path( ).end( ), id.simpleId( ) );
781 }else{
783 const Ast::SearchContext & context = id.searchContext( );
786 size_t pos = lookupPrefix( context.lexicalPath( )->begin( ), context.lexicalPath( )->end( ), id.path( ), id.simpleId( ) );
787 if( pos != NOT_FOUND )
788 return pos;
791 for( RefCountPtr< const Ast::LookinPathStack > i( context.lookinStack( ) ); i != NullPtr< const Ast::LookinPathStack >( ); i = i->cdr( ) ){
792 size_t pos = lookupSuffix( i->car( )->begin( ), i->car( )->end( ), id.simpleId( ) );
793 if( pos != NOT_FOUND )
794 return pos;
797 return NOT_FOUND;
802 size_t
803 Ast::IdentifierTree::lookup( const Ast::PlacedIdentifier & id ) const
805 return lookupSuffix( id.absolutePath( ).begin( ), id.absolutePath( ).end( ), id.simpleId( ) );
808 size_t
809 Ast::IdentifierTree::lookupPrefix( Ast::NamespacePath::const_iterator begin, const Ast::NamespacePath::const_iterator & end, const Ast::NamespacePath & relativePath, const char * simpleId ) const
811 if( begin != end ){
812 typedef typeof namespaces_ MapType;
813 MapType::const_iterator j = namespaces_.find( *begin );
814 if( j != namespaces_.end( ) ){
816 size_t pos = j->second->lookupPrefix( ++begin, end, relativePath, simpleId );
817 if( pos != NOT_FOUND )
818 return pos;
823 return lookupSuffix( relativePath.begin( ), relativePath.end( ), simpleId );
826 size_t
827 Ast::IdentifierTree::lookupSuffix( Ast::NamespacePath::const_iterator begin, const Ast::NamespacePath::const_iterator & end, const char * simpleId ) const
829 if( begin == end ){
831 typedef typeof simpleIdentifiers_ MapType;
832 MapType::const_iterator i = simpleIdentifiers_.find( simpleId );
833 if( i == simpleIdentifiers_.end( ) )
834 return NOT_FOUND;
836 return i->second;
838 }else{
840 typedef typeof namespaces_ MapType;
841 MapType::const_iterator j = namespaces_.find( *begin );
842 if( j == namespaces_.end( ) )
843 return NOT_FOUND;
845 return j->second->lookupSuffix( ++begin, end, simpleId );
850 size_t
851 Ast::IdentifierTree::lookupPrefix( Ast::NamespacePath::const_iterator begin, const Ast::NamespacePath::const_iterator & end, const Ast::NamespacePath & aliasPath, const Ast::Identifier & id ) const
853 /* Note that this function is only used for relative namespace aliases. This means that id will have the form of an absolute identifier,
854 * ::Alias::A::B::...::x
855 * where ::Alias is being expanded to a relative namespace path, and the par beginning wth A:: is what gets appended to the expanded alias.
858 if( begin != end ){
859 typedef typeof namespaces_ MapType;
860 MapType::const_iterator j = namespaces_.find( *begin );
861 if( j != namespaces_.end( ) ){
863 size_t pos = j->second->lookupPrefix( ++begin, end, aliasPath, id );
864 if( pos != NOT_FOUND )
865 return pos;
870 return lookupSuffix( aliasPath.begin( ), aliasPath.end( ), id );
873 size_t
874 Ast::IdentifierTree::lookupSuffix( Ast::NamespacePath::const_iterator begin, const Ast::NamespacePath::const_iterator & end, const Ast::Identifier & id ) const
876 /* Note that this function is only used for absolute namespace aliases. This means that id will have the form of an absolute identifier,
877 * ::Alias::A::B::...::x
878 * where ::Alias is being expanded to an absolute namespace path, and the par beginning wth A:: is what gets appended to the expanded alias.
881 if( begin == end ){
883 Ast::NamespacePath::const_iterator idBegin = id.path( ).begin( );
884 ++idBegin;
886 return lookupSuffix( idBegin, id.path( ).end( ), id.simpleId( ) );
888 }else{
890 typedef typeof namespaces_ MapType;
891 MapType::const_iterator j = namespaces_.find( *begin );
892 if( j == namespaces_.end( ) )
893 return NOT_FOUND;
895 return j->second->lookupSuffix( ++begin, end, id );
901 Ast::PlacedIdentifier
902 Ast::IdentifierTree::reverseMap( size_t pos ) const
904 const char * simpleId;
905 std::list< const char * > * absolutePath = reverseMapHelper( pos, & simpleId );
906 if( absolutePath == NULL )
907 throw Exceptions::InternalError( "Ast::IdentifierTree::reverseMap failure." );
908 return Ast::PlacedIdentifier( absolutePath, simpleId );
911 std::list< const char * > *
912 Ast::IdentifierTree::reverseMapHelper( size_t pos, const char ** simpleIdDst ) const
915 typedef typeof simpleIdentifiers_ MapType;
916 for( MapType::const_iterator i = simpleIdentifiers_.begin( ); i != simpleIdentifiers_.end( ); ++i ){
917 if( i->second == pos )
919 std::list< const char * > * result( new std::list< const char * > );
920 *simpleIdDst = i->first;
921 return result;
927 typedef typeof namespaces_ MapType;
928 for( MapType::const_iterator i = namespaces_.begin( ); i != namespaces_.end( ); ++i ){
929 std::list< const char * > * path = i->second->reverseMapHelper( pos, simpleIdDst );
930 if( path == NULL )
931 continue;
932 path->push_front( i->first );
933 return path;
937 return NULL;
940 void
941 Ast::IdentifierTree::dumpMap( std::map< Ast::PlacedIdentifier, size_t > * dst ) const
943 Ast::NamespacePath path;
944 dumpMap( dst, & path );
947 void
948 Ast::IdentifierTree::dumpMap( std::map< Ast::PlacedIdentifier, size_t > * dst, Ast::NamespacePath * path ) const
951 typedef typeof simpleIdentifiers_ MapType;
952 typedef typeof *dst DstType;
953 for( MapType::const_iterator i = simpleIdentifiers_.begin( ); i != simpleIdentifiers_.end( ); ++i ){
954 dst->insert( DstType::value_type( Ast::PlacedIdentifier( *path, i->first ), i->second ) );
959 typedef typeof namespaces_ MapType;
960 for( MapType::const_iterator i = namespaces_.begin( ); i != namespaces_.end( ); ++i ){
961 path->push_back( i->first );
962 i->second->dumpMap( dst, path );
963 path->pop_back( );
969 Ast::StateID Ast::AnalysisEnvironment::nextStateID = 1;
971 Ast::AnalysisEnvironment::AnalysisEnvironment( PtrOwner_back_Access< std::list< Ast::AnalysisEnvironment * > > & deleter, Ast::AnalysisEnvironment * parent, const Ast::IdentifierTree * bindings, const Ast::IdentifierTree * stateBindings )
972 : parent_( parent ),
973 level_( ( parent_ == 0 ) ? 0 : ( parent_->level_ + 1 ) ),
974 bindings_( bindings ), dynamicKeyBindings_( 0 ),
975 stateBindings_( stateBindings ), dynamicStateKeyBindings_( 0 ),
976 functionBoundary_( false )
978 deleter.push_back( this );
979 updateBindings( );
982 Ast::AnalysisEnvironment::~AnalysisEnvironment( )
985 void
986 Ast::AnalysisEnvironment::updateBindings( )
988 states_.reserve( stateBindings_->size( ) );
989 while( states_.size( ) < stateBindings_->size( ) )
991 states_.push_back( nextStateID );
992 ++nextStateID;
996 Ast::AnalysisEnvironment *
997 Ast::AnalysisEnvironment::getParent( ) const
999 if( isBaseEnvironment( ) )
1001 throw Exceptions::MiscellaneousRequirement( "Trying to find the parent of the top level analysis environment." );
1003 return parent_;
1006 void
1007 Ast::AnalysisEnvironment::activateFunctionBoundary( )
1009 functionBoundary_ = true;
1012 void
1013 Ast::AnalysisEnvironment::setupDynamicKeyVariables( const Ast::IdentifierTree * dynamicKeyBindings )
1015 dynamicKeyBindings_ = dynamicKeyBindings;
1018 void
1019 Ast::AnalysisEnvironment::setupDynamicStateKeyVariables( const Ast::IdentifierTree * dynamicStateKeyBindings )
1021 dynamicStateKeyBindings_ = dynamicStateKeyBindings;
1024 size_t
1025 Ast::AnalysisEnvironment::findLocalVariablePosition( const Ast::SourceLocation & loc, const Ast::PlacedIdentifier & id ) const
1027 size_t pos = bindings_->lookup( id );
1028 if( pos == Ast::IdentifierTree::NOT_FOUND )
1030 throw Exceptions::InternalError( loc, "Environment::findLocalPosition failed" );
1032 return pos;
1035 void
1036 Kernel::Environment::define( size_t pos, const Kernel::VariableHandle & val )
1038 if( (*values_)[ pos ] != NullPtr< Kernel::Variable >( ) )
1040 throw Exceptions::RedefiningLexical( bindings_->reverseMap( pos ) );
1043 (*values_)[ pos ] = val;
1046 Kernel::Environment::LexicalKey
1047 Ast::AnalysisEnvironment::findLexicalVariableKey( const Ast::SourceLocation & loc, const Ast::Identifier & id ) const
1049 size_t pos = bindings_->lookup( id );
1050 if( pos == Ast::IdentifierTree::NOT_FOUND )
1052 if( isBaseEnvironment( ) )
1054 Ast::theAnalysisErrorsList.push_back( new Exceptions::LookupUnknown( loc, id, Ast::Identifier::VARIABLE ) );
1055 return Kernel::Environment::theMissingKey;
1057 return parent_->findLexicalVariableKey( loc, id ).oneAbove( );
1060 return LexicalKey( 0, pos );
1063 Ast::PlacedIdentifier
1064 Ast::AnalysisEnvironment::reverseMapLexicalVariable( const LexicalKey & lexKey ) const
1066 const AnalysisEnvironment * env = this;
1067 for( size_t i = lexKey.up_; i > 0; --i )
1069 env = env->getParent( );
1072 return env->bindings_->reverseMap( lexKey.pos_ );
1075 void
1076 Kernel::Environment::lookup( const Kernel::Environment::LexicalKey & lexKey, Kernel::EvalState * evalState ) const
1078 const Environment * env = this;
1079 for( size_t i = lexKey.up_; i > 0; --i )
1081 env = env->getParent( );
1084 env->lookup( lexKey.pos_, evalState );
1087 void
1088 Kernel::Environment::lookup( size_t pos, Kernel::EvalState * evalState ) const
1090 Kernel::VariableHandle res = (*values_)[ pos ];
1091 if( res == NullPtr< Kernel::Variable >( ) )
1093 throw Exceptions::UninitializedAccess( );
1096 Kernel::ContRef cont = evalState->cont_;
1097 cont->takeHandle( res, evalState );
1100 Kernel::VariableHandle
1101 Kernel::Environment::getVarHandle( const Kernel::Environment::LexicalKey & lexKey )
1103 Environment * env = this;
1104 for( size_t i = lexKey.up_; i > 0; --i )
1106 env = env->getParent( );
1109 return env->getVarHandle( lexKey.pos_ );
1112 Kernel::VariableHandle
1113 Kernel::Environment::getVarHandle( size_t pos )
1115 return (*values_)[ pos ];
1118 Kernel::Environment::LexicalKey
1119 Ast::AnalysisEnvironment::findLexicalTypeKey( const Ast::SourceLocation & loc, const Ast::Identifier & id ) const
1121 size_t pos = bindings_->lookup( id );
1122 if( pos == Ast::IdentifierTree::NOT_FOUND )
1124 if( isBaseEnvironment( ) )
1126 Ast::theAnalysisErrorsList.push_back( new Exceptions::LookupUnknown( loc, id, Ast::Identifier::TYPE ) );
1127 return Kernel::Environment::theMissingKey;
1129 return parent_->findLexicalTypeKey( loc, id ).oneAbove( );
1132 return LexicalKey( 0, pos );
1136 size_t
1137 Ast::AnalysisEnvironment::findLocalStatePosition( const Ast::SourceLocation & loc, const Ast::PlacedIdentifier & id ) const
1139 size_t pos = stateBindings_->lookup( id );
1140 if( pos == Ast::IdentifierTree::NOT_FOUND )
1142 throw Exceptions::InternalError( loc, "Environment::findLocalStatePosition failed" );
1144 return pos;
1147 Kernel::Environment::LexicalKey
1148 Ast::AnalysisEnvironment::findLexicalStateKey( const Ast::SourceLocation & loc, const Ast::Identifier & id ) const
1150 size_t pos = stateBindings_->lookup( id );
1151 if( pos == Ast::IdentifierTree::NOT_FOUND )
1153 if( isBaseEnvironment( ) )
1155 Ast::theAnalysisErrorsList.push_back( new Exceptions::LookupUnknown( loc, id, Ast::Identifier::STATE ) );
1156 return Kernel::Environment::theMissingKey;
1158 if( functionBoundary_ )
1160 // If the state is not found at all, this will throw an error.
1161 parent_->findLexicalStateKey( loc, id ).oneAbove( ); // Ignore the result!
1162 // If no error is thrown, we inform the user that the state is outside a function boundary.
1163 Ast::theAnalysisErrorsList.push_back( new Exceptions::StateBeyondFunctionBoundary( loc, id ) );
1164 return Kernel::Environment::theMissingKey;
1166 return parent_->findLexicalStateKey( loc, id ).oneAbove( );
1169 return LexicalKey( 0, pos );
1172 Ast::StateID
1173 Ast::AnalysisEnvironment::getStateID( const LexicalKey & lexKey ) const
1175 const Ast::AnalysisEnvironment * env = this;
1176 for( size_t i = lexKey.up_; i > 0; --i )
1178 env = env->getParent( );
1181 return env->getStateID( lexKey.pos_ );
1184 Ast::StateID
1185 Ast::AnalysisEnvironment::getStateID( size_t pos ) const
1187 return states_[ pos ];
1190 Ast::StateID
1191 Ast::AnalysisEnvironment::getTheAnyStateID( )
1193 return -1;
1196 void
1197 Kernel::Environment::introduceState( size_t pos, Kernel::State * state )
1199 if( (*states_)[ pos ] != NullPtr< Kernel::State >( ) )
1201 throw Exceptions::InternalError( "Better error message needed when a state is introduced more than once." );
1202 // throw Exceptions::RedefiningLexical( reverseMap( pos ) );
1205 (*states_)[ pos ] = state;
1208 void
1209 Kernel::Environment::freeze( size_t pos, Kernel::EvalState * evalState, const Ast::SourceLocation & loc )
1211 if( (*states_)[ pos ] == NullPtr< Kernel::State >( ) )
1213 // This is a static inconsistency, so it should be detected before we reach here...
1214 throw Exceptions::FreezingUndefined( loc, stateBindings_->reverseMap( pos ) );
1217 Kernel::StateHandle & state = (*states_)[ pos ];
1219 state->freeze( evalState, loc );
1222 void
1223 Kernel::Environment::peek( const LexicalKey & lexKey, Kernel::EvalState * evalState, const Ast::SourceLocation & loc )
1225 getStateHandle( lexKey )->peek( evalState, loc );
1228 void
1229 Kernel::Environment::tackOn( const LexicalKey & lexKey, Kernel::EvalState * evalState, const RefCountPtr< const Lang::Value > & piece, const Ast::SourceLocation & callLoc )
1231 getStateHandle( lexKey )->tackOn( evalState, piece, callLoc );
1234 Kernel::StateHandle
1235 Kernel::Environment::getStateHandle( const LexicalKey & lexKey )
1237 Environment * env = this;
1238 for( size_t i = lexKey.up_; i > 0; --i )
1240 env = env->getParent( );
1243 return env->getStateHandle( lexKey.pos_ );
1246 Kernel::StateHandle
1247 Kernel::Environment::getStateHandle( size_t pos )
1249 Kernel::StateHandle res = (*states_)[ pos ];
1250 if( res == NullPtr< Kernel::State >( ) )
1252 throw Exceptions::UninitializedAccess( );
1254 return res;
1259 size_t
1260 Ast::AnalysisEnvironment::findLocalDynamicPosition( const Ast::SourceLocation & loc, const Ast::PlacedIdentifier & id ) const
1262 if( dynamicKeyBindings_ == 0 )
1264 throw Exceptions::InternalError( "Environment::findLocalDynamicPosition called with dynamicKeyBindings_ == 0." );
1266 size_t pos = dynamicKeyBindings_->lookup( id );
1267 if( pos == Ast::IdentifierTree::NOT_FOUND )
1269 throw Exceptions::InternalError( loc, "Environment::findLocalDynamicPosition failed" );
1271 return pos;
1274 void
1275 Kernel::Environment::defineDynamic( const Ast::PlacedIdentifier * debugId, size_t pos, const RefCountPtr< const Lang::Function > & filter, const Kernel::VariableHandle & defaultVal )
1277 if( dynamicKeyValues_ == 0 )
1279 throw Exceptions::InternalError( "Environment::defineDynamic called with dynamicKeyValues_ == 0." );
1281 if( pos > dynamicKeyValues_->size( ) )
1283 throw Exceptions::InternalError( "Environment::defineDynamic called with pos out of range." );
1285 if( (*dynamicKeyValues_)[ pos ] != 0 )
1287 throw Exceptions::RedefiningDynamic( dynamicKeyBindings_->reverseMap( pos ) );
1290 (*dynamicKeyValues_)[ pos ] = new Kernel::UserDynamicVariableProperties( debugId,
1291 Kernel::DynamicEnvironment::getFreshKey( ),
1292 filter,
1293 defaultVal );
1296 Kernel::Environment::LexicalKey
1297 Ast::AnalysisEnvironment::findLexicalDynamicKey( const Ast::SourceLocation & loc, const Ast::Identifier & id ) const
1299 if( dynamicKeyBindings_ == 0 )
1301 if( isBaseEnvironment( ) )
1303 goto error;
1305 return parent_->findLexicalDynamicKey( loc, id ).oneAbove( );
1308 size_t pos = dynamicKeyBindings_->lookup( id );
1309 if( pos == Ast::IdentifierTree::NOT_FOUND )
1311 if( isBaseEnvironment( ) )
1313 goto error;
1315 return parent_->findLexicalDynamicKey( loc, id ).oneAbove( );
1318 return LexicalKey( 0, pos );
1321 error:
1322 Ast::theAnalysisErrorsList.push_back( new Exceptions::LookupUnknown( loc, id, Ast::Identifier::DYNAMIC_VARIABLE ) );
1323 return Kernel::Environment::theMissingKey;
1327 const Kernel::DynamicVariableProperties &
1328 Kernel::Environment::lookupDynamicVariable( const LexicalKey & lexKey ) const
1330 const Environment * env = this;
1331 for( size_t i = lexKey.up_; i > 0; --i )
1333 env = env->getParent( );
1336 return env->lookupDynamicVariable( lexKey.pos_ );
1339 const Kernel::DynamicVariableProperties &
1340 Kernel::Environment::lookupDynamicVariable( size_t pos ) const
1342 const DynamicVariableProperties * res = (*dynamicKeyValues_)[ pos ];
1343 if( res == 0 )
1345 throw Exceptions::UninitializedAccess( );
1347 return *res;
1350 size_t
1351 Ast::AnalysisEnvironment::findLocalDynamicStatePosition( const Ast::SourceLocation & loc, const Ast::PlacedIdentifier & id ) const
1353 if( dynamicStateKeyBindings_ == 0 )
1355 throw Exceptions::InternalError( "Environment::findLocalDynamicStatePosition called with dynamicStateKeyBindings_ == 0." );
1357 size_t pos = dynamicStateKeyBindings_->lookup( id );
1358 if( pos == Ast::IdentifierTree::NOT_FOUND )
1360 throw Exceptions::InternalError( loc, "Environment::findLocalDynamicStatePosition failed" );
1362 return pos;
1365 void
1366 Kernel::Environment::defineDynamicState( const Ast::PlacedIdentifier * debugId, size_t pos, Kernel::EvalState * evalState, Ast::StateReference * defaultState )
1368 if( dynamicStateKeyValues_ == 0 )
1370 throw Exceptions::InternalError( "Environment::defineDynamicState called with dynamicStateKeyValues_ == 0." );
1372 if( pos > dynamicStateKeyValues_->size( ) )
1374 throw Exceptions::InternalError( "Environment::defineDynamicState called with pos out of range." );
1376 if( (*dynamicStateKeyValues_)[ pos ] != 0 )
1378 throw Exceptions::RedefiningDynamic( dynamicStateKeyBindings_->reverseMap( pos ) );
1381 (*dynamicStateKeyValues_)[ pos ] = new Kernel::UserDynamicStateProperties( debugId,
1382 // Kernel::DynamicEnvironment::getFreshKey( ),
1383 evalState->env_,
1384 evalState->dyn_,
1385 defaultState );
1389 Kernel::Environment::LexicalKey
1390 Ast::AnalysisEnvironment::findLexicalDynamicStateKey( const Ast::SourceLocation & loc, const Ast::Identifier & id ) const
1392 if( dynamicStateKeyBindings_ == 0 )
1394 return parent_->findLexicalDynamicStateKey( loc, id ).oneAbove( );
1397 size_t pos = dynamicStateKeyBindings_->lookup( id );
1398 if( pos == Ast::IdentifierTree::NOT_FOUND )
1400 if( isBaseEnvironment( ) )
1402 Ast::theAnalysisErrorsList.push_back( new Exceptions::LookupUnknown( loc, id, Ast::Identifier::DYNAMIC_STATE ) );
1403 return Kernel::Environment::theMissingKey;
1405 return parent_->findLexicalDynamicStateKey( loc, id ).oneAbove( );
1408 return LexicalKey( 0, pos );
1411 const Kernel::DynamicStateProperties &
1412 Kernel::Environment::lookupDynamicState( const LexicalKey & lexKey ) const
1414 const Environment * env = this;
1415 for( size_t i = lexKey.up_; i > 0; --i )
1417 env = env->getParent( );
1420 return env->lookupDynamicState( lexKey.pos_ );
1423 const Kernel::DynamicStateProperties &
1424 Kernel::Environment::lookupDynamicState( size_t pos ) const
1426 const DynamicStateProperties * res = (*dynamicStateKeyValues_)[ pos ];
1427 if( res == 0 )
1429 throw Exceptions::UninitializedAccess( );
1431 return *res;
1435 size_t
1436 Kernel::Environment::size( ) const
1438 return bindings_->size( );
1442 void
1443 Kernel::Environment::print( std::ostream & os ) const
1445 std::set< Ast::PlacedIdentifier > shadowed;
1446 std::set< Ast::PlacedIdentifier > shadowedStates;
1447 recursivePrint( os, & shadowed, & shadowedStates );
1450 size_t
1451 Kernel::Environment::recursivePrint( std::ostream & os, std::set< Ast::PlacedIdentifier > * shadowed, std::set< Ast::PlacedIdentifier > * shadowedStates ) const
1453 typedef std::map< Ast::PlacedIdentifier, size_t > IdMap;
1455 std::set< Ast::PlacedIdentifier > shadowedBefore( *shadowed );
1456 std::set< Ast::PlacedIdentifier > shadowedStatesBefore( *shadowedStates );
1458 size_t depth = 0;
1459 if( ! isBaseEnvironment( ) )
1462 IdMap tmp;
1463 bindings_->dumpMap( & tmp );
1464 for( IdMap::const_iterator i = tmp.begin( ); i != tmp.end( ); ++i ){
1465 shadowed->insert( shadowed->begin( ), i->first );
1469 IdMap tmp;
1470 stateBindings_->dumpMap( & tmp );
1471 for( IdMap::const_iterator i = tmp.begin( ); i != tmp.end( ); ++i ){
1472 shadowedStates->insert( shadowedStates->begin( ), i->first );
1475 depth = parent_->recursivePrint( os, shadowed, shadowedStates ) + 1;
1478 std::string indentation = std::string( depth, ' ' );
1480 size_t width = 1;
1481 for( size_t tmp = bindings_->size( ); tmp >= 10; tmp /= 10, ++width )
1485 size_t tmp = ( 29 - 4 ) - strlen( debugName_ );
1486 if( tmp < 2 || tmp > 29 ) /* the latter case corresponds to an underflow in the subtraction */
1488 tmp = 2;
1490 os << indentation << std::string( tmp / 2, '-' ) << "( " << debugName_ << " )" << std::string( tmp - tmp / 2, '-' ) << std::endl ;
1492 if( ! isBaseEnvironment( ) )
1495 IdMap tmp;
1496 bindings_->dumpMap( & tmp );
1497 for( IdMap::const_iterator i = tmp.begin( ); i != tmp.end( ); ++i ){
1498 os << indentation << std::setw(width) << i->second ;
1499 if( shadowedBefore.find( i->first ) != shadowedBefore.end( ) )
1501 os << "^" ;
1503 else
1505 os << " " ;
1507 os << " " ;
1508 i->first.show( os, Ast::Identifier::VARIABLE );
1509 os << " : " ;
1510 if( (*values_)[ i->second ] == NullPtr< Kernel::Variable >( ) )
1512 os << "< Uninitialized >" ;
1514 else if( (*values_)[ i->second ]->isThunk( ) )
1516 os << "< thunk >" ;
1518 else if( dynamic_cast< const Lang::Instance * >( (*values_)[ i->second ]->getUntyped( ).getPtr( ) ) == 0 )
1520 (*values_)[ i->second ]->getUntyped( )->show( os );
1522 else
1524 os << "..." ;
1526 os << std::endl ;
1530 IdMap tmp;
1531 stateBindings_->dumpMap( & tmp );
1532 for( IdMap::const_iterator i = tmp.begin( ); i != tmp.end( ); ++i ){
1533 os << indentation << std::setw(width) << i->second ;
1534 if( shadowedStatesBefore.find( i->first ) != shadowedStatesBefore.end( ) )
1536 os << "^" ;
1538 else
1540 os << " " ;
1542 os << " " ;
1543 i->first.show( os, Ast::Identifier::STATE );
1544 os << " :: " ;
1545 if( (*states_)[ i->second ] == NullPtr< Kernel::State >( ) )
1547 os << "< Uninitialized >" ;
1549 else
1551 os << (*states_)[ i->second ]->getTypeName( ) ;
1553 os << std::endl ;
1557 else
1559 os << indentation << "<< global env >>" << std::endl ;
1562 os << indentation << "-- -- -- -- -- -- -- -- -- --" << std::endl ;
1564 return depth;