/*
 * function definitions stored in a hash
 */

#include <stdio.h>

#include <hash.h>
#include "types.h"
#include "funchash.h"


extern int yyerrors;
extern void yyerror(const char *str);
extern BOOL verbose;


/* the hash */
static hash funchash = NULL;


/* helper function: print (k,v) pair */
static void printkv( FILE *out, key k, value v )
{
	print_fdefn( out, (fdefn)v );
	fprintf( out, "\n" );
}


/* helper function: free value (an fdefn) */
static void freev( value v )
{
	//free_fdefn( (fdefn)v );
}


void init_funchash( void )
{
	funchash = hashCreate( &printkv, &freev, NULL );
	if( verbose )
	{
		fprintf( stderr, "\tInitialized funchash\n" );
		//hashDump( stderr, funchash );
	}
}


void destroy_funchash( void )
{
	hashFree( funchash );
}


BOOL lookup_function( char *name )
{
	value v = hashFind( funchash, name );
	return( v != NULL );
}


BOOL lookup_function_flagerror( char *name )
{
	value v = hashFind( funchash, name );
	if( v == NULL )
	{
		char mesg[1024];
		sprintf( mesg, "undefined function '%s'", name );
		yyerror( mesg );
		return 0;
	}
	return 1;
}


void define_function( char *name, fdefn defn )
{
	value v = hashFind( funchash, name );
	if( v == NULL )
	{
		hashSet( funchash, name, (value)defn );
		if( yyerrors==0 && verbose )
		{
			fprintf( stderr, "\t- defined function %s( int )\n",
				 name );
		}
	} else
	{
		char mesg[1024];
		sprintf( mesg, "redefined function '%s'", name );
		yyerror( mesg );
	}
}


void foreach_function( fdefcb cb )
{
	hashForeach( funchash, (foreachcbfunc)cb, NULL );
}


void print_funchash( FILE *out )
{
	//fprintf( stderr, "debug: funchash:\n" );
	hashDump( out, funchash );
}
