
#define OTALK_TOP
#include "otalk.h"
#include "scanner.h"
#include "compile.h"
#include <assert.h>


void otalk_last(void)
{
  extern int cache_hit;
  extern int cache_miss;
  extern int global_cache_hit;
  extern int global_cache_miss;

  printf("Cache Hits:   %d\n",cache_hit);
  printf("Cache Misses: %d\n",cache_miss);
  printf("Global Cache Hits:   %d\n",global_cache_hit);
  printf("Global Cache Misses: %d\n",global_cache_miss);


}

void otalk_init(void)
{

  g_stack = create_stack(1000);
  g_stackpointer = g_stack;

  init_objects();
  init_hashtables();
}

/* ----------------------------------------------------------------------
   call_method()
   ---------------------------------------------------------------------- */
T_OBJECT find_method(T_OBJECT o,T_OBJECT symbol)
{
  T_OBJECT class = CLASS(o);
  T_OBJECT liste;
  int i,max;

  do {
    liste = CLASS_METHODS(class);
    max = NUMBER(VECTOR_FILL(liste));

    for (i=1; i <= max; ++i) {
      /* printf("Search %p\n",VECTOR_ENTRY(liste,i)); */
      if (O_METHOD_NAME(VECTOR_ENTRY(liste,i)) == symbol) {	
	return VECTOR_ENTRY(liste,i);
      }
    }
    if (class == g_top_object_class) {
      puts(STRING_CHARS(symbol));
      otalk_error("Kann Methode nicht ausführen.\n");
    }
    class = CLASS_SUPER(class);
    assert(class!=NULL);
  } while(1);

  return NULL;
}

int g_par_debug = 0;

void handle_args(int argc, char** argv)
{
  int i;

  for (i=0; i<argc; ++i) {
    if (!strcmp("DEBUG",argv[i]))
      g_par_debug = 1;
  }
}

void main(int argc, char** argv)
{
  T_OBJECT method;

  handle_args(argc,argv);

  otalk_init();

  read_file("tlib/Object.ot");
  read_file("tlib/Class.ot");
  read_file("tlib/MetaClass.ot");
  read_file("tlib/MetaMetaClass.ot");
  read_file("tlib/Method.ot");
  read_file("tlib/FixedVector.ot");
  read_file("tlib/Integer.ot");
  read_file("tlib/String.ot");
  read_file("tlib/Symbol.ot");
  read_file("tlib/Nil.ot");
  read_file("tlib/True.ot");
  read_file("tlib/False.ot");
  read_file("tlib/classes.ot");
  
  /*
  print_class(g_top_object_class);
  print_class(g_top_class_class);
  print_class(g_primitive_class_vector);
  print_class(g_primitive_class_symbol);
  print_class(g_primitive_class_method);
  print_class(g_primitive_class_bytevector);
  print_class(g_primitive_class_string);
  print_class(CLASS(g_primitive_class_string));
  print_class(g_primitive_class_number);
  print_class(g_primitive_class_true);
  print_class(g_primitive_class_false);
  print_class(g_primitive_class_nil);
  print_class(g_primitive_class_meta);
  print_class(g_primitive_class_meta_meta);
  print_class(g_primitive_class_exception);
  */
  STACK_PUSH(g_stackpointer,make_number(20));
  method = find_method(make_number(20),make_symbol("install_classes()"));
  interpreter_main_loop(g_stackpointer,method,0);
  STACK_POP(g_stackpointer,1);

  read_file("test.txt");
  /*
  print_class(class_for("ClassRope"));
  print_class(class_for("ClassString"));
  print_class(CLASS(g_primitive_class_string)); */

  STACK_PUSH(g_stackpointer,make_number(100));
  STACK_PUSH(g_stackpointer,make_number(20));
  STACK_PUSH(g_stackpointer,make_number(21));
  method = find_method(make_number(20),make_symbol("test()"));
  printf("Pointer: %p\n",method);
  /* print_method(method); */
  interpreter_main_loop(g_stackpointer,method,2);

  printf("\n\nBye\n\n");
  otalk_last();
  exit(0);
}

/*eof*/
