//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// StackTable.cc -- 
//
// Author           : Richard C. Bilson
// Created On       : Sun May 17 21:45:15 2015
// Last Modified By : Peter A. Buhr
// Last Modified On : Tue May 19 16:51:53 2015
// Update Count     : 3
//

#include <cassert>

#include "StackTable.h"

namespace SymTab {
	template< typename Element, typename ConflictFunction >
	StackTable< Element, ConflictFunction >::StackTable() : scopeLevel( 0 ) {
	}

	template< typename Element, typename ConflictFunction >
	void StackTable< Element, ConflictFunction >::enterScope() {
		scopeLevel++;
	}

	template< typename Element, typename ConflictFunction >
	void StackTable< Element, ConflictFunction >::leaveScope() {
		for ( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
			std::stack< Entry >& entry = it->second;
			if ( ! entry.empty() && entry.top().second == scopeLevel ) {
				entry.pop();
			} // if
		} // for
		scopeLevel--;
		assert( scopeLevel >= 0 );
	}

	template< typename Element, typename ConflictFunction >
	void StackTable< Element, ConflictFunction >::add( Element *type ) {
		std::stack< Entry >& entry = table[ type->get_name() ];
		if ( ! entry.empty() && entry.top().second == scopeLevel ) {
			entry.top().first = conflictFunction( entry.top().first, type );
		} else {
			entry.push( Entry( type, scopeLevel ) );
		} // if
	}

	template< typename Element, typename ConflictFunction >
	void StackTable< Element, ConflictFunction >::add( std::string fwdDeclName ) {
		add( new Element( fwdDeclName ) );
	}

	template< typename Element, typename ConflictFunction >
	Element *StackTable< Element, ConflictFunction >::lookup( std::string id ) const {
		typename TableType::const_iterator it = table.find( id );
		if ( it == table.end() ) {
			return 0;
		} else if ( ! it->second.empty() ) {
			return it->second.top().first;
		} else {
			return 0;
		} // if
	}

	template< typename Element, typename ConflictFunction >
	void StackTable< Element, ConflictFunction >::dump( std::ostream &os ) const {
		for ( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
			const std::stack< Entry >& entry = it->second;
			if ( ! entry.empty() && entry.top().second == scopeLevel ) {
				os << it->first << std::endl;
			} // if
		} // for
	}
} // namespace SymTab

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
