/*
 * named constants stored in a hash
 */

#include <stdio.h>
#include <stdlib.h>

#include <hash.h>

#include "types.h"
#include "consthash.h"


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


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


/* helper function: print (k,v) pair */
static void printkv( FILE *out, key k, value v )
{
	fprintf( out, "\t  %.20s: %ld\n", k, (long)v );
}


/* helper function: free value */
static void freev( value v )
{
	/* DO NOTHING */
}


void init_consthash( int argc, char **argv )
{
	consthash = hashCreate( &printkv, &freev, NULL );
	int i;
	for( i=1; i<argc; i++ )
	{
		char key[8];
		sprintf( key, "arg%d", i );
		hashSet( consthash, key, (value)atol(argv[i]) );
	}
	long power;
	for( i=0, power=1; i<32; i++, power<<=1 )
	{
		char key[8];
		sprintf( key, "t%d", i );
		hashSet( consthash, key, (value)power );
	}
	hashSet( consthash, "howmanyroads", (value)42 );
	hashSet( consthash, "one",   (value)1 );
	hashSet( consthash, "two",   (value)2 );
	hashSet( consthash, "three", (value)3 );
	hashSet( consthash, "four",  (value)4 );
	hashSet( consthash, "five",  (value)5 );
	hashSet( consthash, "six",   (value)6 );
	hashSet( consthash, "seven", (value)7 );
	hashSet( consthash, "eight", (value)8 );
	hashSet( consthash, "nine",  (value)9 );
	hashSet( consthash, "ten",   (value)10 );
	if( verbose )
	{
		fprintf( stderr, "\n\tInitialized consthash containing:\n" );
		hashDump( stderr, consthash );
	}
}


void destroy_consthash( void )
{
	hashFree( consthash );
}


int lookup_const( char *constname )
{
	value v = NULL;
	BOOL present = hashPresent( consthash, constname, &v );
	if( !present )
	{
		char mesg[1024];
		sprintf( mesg, "undefined constant '%s'", constname );
		yyerror( mesg );
		return -1;
	}
	return (int)(long)v;
}


void foreach_constant( constkvcb cb, void *extra )
{
	hashForeach( consthash, (foreachcbfunc)cb, extra );
}
