/* Copyright (C) 2001 Michael Leonhard
 * Mike Leonhard
 * mike at tamale dot net
 * http://tamale.net/
 */

#include <stdlib.h>
#include "sebae.h"
#include "build.h"

#define STACKSIZE 1048576
#define MEMSIZE 13
#define fooSTACKSIZE 1024
#define fooMEMSIZE 1048576

int main( int argc, char *argv[] ) {
	struct SebaeVM *vm;
	int ret;
	
	/* check command line */
        if( argc != 2 ) return usage();

	/* new VM */
	vm = Sebae_VM_New( STACKSIZE, MEMSIZE );
	
	/* no VM */
	if( vm == NULL ) {
		printf( "VM creation failed\n" );
		return 1;
		}
	
	/* load bytecode file */
	ret = Sebae_Bytecode_LoadFile( vm, argv[1] );
	
	/* load failed */
	if( ret == -1 ) return Sebae_PrintError( vm );

	/* prepare vm for execution */
	Sebae_VM_Rewind( vm );

	/* loop vm */
	while( 1 ) {
		/* perform one instruction */
		ret = Sebae_VM_Tick( vm );
		
		/* VM error */
		if( ret == -1 ) {
			Sebae_PrintError( vm );
			break;
			}

		/* VM halted */
		if( ret == 0 ) break;
		}

	/* print stack */
	for( ret = 0; ret < vm->stackheight; ret++ ) printf( "stack[%d] = 0x%08X or %d or %f;\n", ret, vm->stack[ret], vm->stack[ret], *(float *)&vm->stack[ret] );
	
	/* print memory */
	for( ret = 0; ret < vm->memsize; ret++ ) printf( " %02X %02X %02X %02X\n", (vm->mem[ret] >> 24) & 0xFF, (vm->mem[ret] >> 16) & 0xFF, (vm->mem[ret] >> 8) & 0xFF, vm->mem[ret] & 0xFF );
	
	/* clean up */
	ret = Sebae_VM_Destroy( vm );

	/* error in clean up */
	if( ret == -1 ) return Sebae_PrintError( vm );

	return 0;
        }

int usage() {
	printf( "Sebae Virtual Machine version %s build %d, %s\n", VERSION, BUILDNUM, BUILDDATE );
	printf( "Mike Leonhard, mike at tamale dot net, http://tamale.net/\n\n" );
	printf( "usage: svm program.seb\n" );
	return 1;
        }
