#ifdef _MSC_VER
#if defined(_DEBUG)
#define _CRTDBG_MAP_ALLOC
#endif
#endif

#include "mk.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#include <string.h>
#ifdef _MSC_VER
#include <locale.h>
#endif

void show_profile_data( MK_VM_STRUCT *vm )
{
	// show profile.
	int count = 0;
	MK_MANAGED_VM_FRAME_ITEM_TABLE *pFrameItemTable = vm->pFrameItemTable;
	MK_MANAGED_VM_FRAME_TABLE *pFrameTable = vm->pFrameTable;
	MK_MANAGED_HASH_TABLE *pHashTable = vm->pHashTable;

	fprintf( stdout, "symbolneme count:%d\n", mk_size_item_hashtable( vm->hashSymbolName) );
	fprintf( stdout, "sizeof memorypool:%d\n", vm->memoryPool->next - vm->memoryPool->memory );
	count = 0;
	do
	{
		count ++;
		pFrameItemTable = pFrameItemTable->previous;
	}
	while( pFrameItemTable );
	fprintf( stdout, "frameitemtable count:%d\n", count );
	count = 0;
	do
	{
		count ++;
		pFrameTable = pFrameTable->previous;
	}
	while( pFrameTable );
	fprintf( stdout, "frametable count:%d\n", count );
	count = 0;
	do
	{
		count ++;
		pHashTable = pHashTable->previous;
	}
	while( pHashTable );
	fprintf( stdout, "hashtable count:%d\n", count );
}

int main( int argc, char **argv )
{
	MK_VM_STRUCT *vm = NULL;
	MK_CHAR *fileName = NULL;
	int retCode = 0;

#ifdef _MSC_VER
#if defined(_DEBUG)
	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
	setlocale( LC_ALL, ".OCP" );
#endif


	if( argc < 2 )
	{
		fprintf( stdout, "%s  Build - %s %s\n", argv[0], __DATE__, __TIME__ );
		return 0;
	}

	fileName = argv[1];
	
	vm = 
		mk_create_object( MK_OBJECT_TYPE_VM_STRUCT );
	mk_vm_initialize( vm );

	retCode = do_compile( vm, fileName );
	if( retCode != 0 )
	{
		retCode = mk_vm_run( vm );
		if( vm->exceptionObject != NULL )
		{
			MK_VM_FRAME_ITEM *pErrorDescription = NULL;
			mk_trace( MK_TRACE_TYPE_ERROR, "unhandle error." );
			mk_find_item_hashtable( vm->exceptionObject->classTypeValue.variables, 
								   mk_get_symbol_name_ptr( vm, "description" ), 
								   (void**)&pErrorDescription );
			if( pErrorDescription != NULL )
				mk_trace( MK_TRACE_TYPE_ERROR, pErrorDescription->stringTypeValue );
		}
#ifdef _DEBUG_DUMP
		show_profile_data( vm );
#endif
	}
	mk_destroy_node( vm->memoryPool, vm );

	return retCode != 0;
}
