/*****
 NAME
 	clangscope.m - source code for CLangScope class
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/clangscope.h>
#include <coconut/chash.h>
#include <coconut/ptext.h>
#include <coconut/fobject.h>

static guint hash_variable(gconstpointer v);
static gboolean equal_variable(gconstpointer s1, gconstpointer s2) ;

@implementation CLangScope

- init
{
	variable_table = [[CHash alloc] initHash: &hash_variable 
	  equal: &equal_variable removeKey: &remove_object_func
	  removeData: &remove_object_func] ;
	return [super init] ;
}

- (void) dealloc
{
	[variable_table release] ;
	[super dealloc] ;
}

- (id <PExpVar>) addVariable: (id <PExpVar>) var
{
	id <PConstStr>	varname ;
	id <PExpVar>	prevvar ;

	if((varname = [var name]) == nil){
		g_message("no name variable are given") ;
		return nil ;
	}
	if((prevvar = [self searchVariable: varname]) != nil){
		return prevvar ;
	} else {
		[varname retain] ; [var retain] ;
		[variable_table add: varname object: var] ;
		return var ;
	}
}

- (id <PExpVar>) searchVariable: (id <PConstStr>) name
{
	return (id <PExpVar>) [variable_table  search: name] ;
}

- print: (id <PIndentStream>) stream
{
	id 	result ;

	[stream putPtr: "(variable_table\n"] ;
	  [stream incLevel] ;
	  	result = [variable_table foreach: @selector(print:) with: stream
		  with: nil] ;
	  [stream decLevel] ;
	[stream putPtr: ")\n"] ;
	return result ;
}

@end

static guint hash_variable(gconstpointer v)
{
	return [(id <PExpVar>) v hashkey] ;
}

static gboolean equal_variable(gconstpointer s1, gconstpointer s2)
{
	id <PExpVar>	var = (id <PExpVar>) s1 ;
	id <PConstStr>	str = (id <PConstStr>) s2 ;
	id <PConstStr>	varname ;

	varname = [var name] ;
	g_assert(varname != nil && str != nil) ;

	return [varname compare: str] == 0 ;
}

