/* libsizzle/profile.c - interpreter profiling
 
  Copyright (C) 2000 Martin Grabmueller <mgrabmue@cs.tu-berlin.de>
 
  This is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.
  
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this package; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA 02111-1307, USA.  */

#if HAVE_CONFIG_H
# include <config.h>
#endif 

#if ENABLE_NLS
# include <libintl.h>
# define _(String) gettext(String)
#else
# define _(String) (String)
#endif

#include "node.h"
#include "eval.h"
#include "capi.h"
#include "profile.h"

unsigned zzz_global_accesses;
unsigned zzz_lloc_accesses;
unsigned zzz_gloc_accesses;
unsigned zzz_tail_calls;
unsigned zzz_evaluate_calls;
unsigned zzz_closure_calls;
unsigned zzz_primitive_calls;
unsigned zzz_immediate_calls;
unsigned zzz_syntactic_calls;

static zzz_scm_t global_accesses_sym;
static zzz_scm_t lloc_accesses_sym;
static zzz_scm_t gloc_accesses_sym;
static zzz_scm_t tail_calls_sym;
static zzz_scm_t evaluate_calls_sym;
static zzz_scm_t closure_calls_sym;
static zzz_scm_t primitive_calls_sym;
static zzz_scm_t immediate_calls_sym;
static zzz_scm_t syntactic_calls_sym;

/*:doc
  profile-stats
  (profile-stats) => alist
  Return an association list with profiling statistics.
  doc:*/
#define FUNC_NAME "profile-stats"
static result_t
profile_stats (zzz_scm_t env, zzz_scm_t * result)
{
  static char * s_func_name = FUNC_NAME;

  *result = zzz_make_list
    (zzz_cons (global_accesses_sym, zzz_make_integer (zzz_global_accesses)),
     zzz_cons (lloc_accesses_sym, zzz_make_integer (zzz_lloc_accesses)),
     zzz_cons (gloc_accesses_sym, zzz_make_integer (zzz_gloc_accesses)),
     zzz_cons (tail_calls_sym, zzz_make_integer (zzz_tail_calls)),
     zzz_cons (evaluate_calls_sym, zzz_make_integer (zzz_evaluate_calls)),
     zzz_cons (closure_calls_sym, zzz_make_integer (zzz_closure_calls)),
     zzz_cons (primitive_calls_sym, zzz_make_integer (zzz_primitive_calls)),
     zzz_cons (syntactic_calls_sym, zzz_make_integer (zzz_syntactic_calls)),
     zzz_cons (immediate_calls_sym, zzz_make_integer (zzz_immediate_calls)),
     NULL);
  return RESULT_SUCCESS;
}
#undef FUNC_NAME

result_t
zzz_init_profile (void)
{
  zzz_global_accesses = 0;
  zzz_lloc_accesses = 0;
  zzz_gloc_accesses = 0;
  zzz_tail_calls = 0;
  zzz_evaluate_calls = 0;
  zzz_closure_calls = 0;
  zzz_primitive_calls = 0;
  zzz_immediate_calls = 0;
  zzz_syntactic_calls = 0;

  zzz_protect_global (&global_accesses_sym);
  zzz_protect_global (&lloc_accesses_sym);
  zzz_protect_global (&gloc_accesses_sym);
  zzz_protect_global (&tail_calls_sym);
  zzz_protect_global (&evaluate_calls_sym);
  zzz_protect_global (&closure_calls_sym);
  zzz_protect_global (&primitive_calls_sym);
  zzz_protect_global (&syntactic_calls_sym);
  zzz_protect_global (&immediate_calls_sym);

  global_accesses_sym = zzz_make_symbol ("global-accesses", -1);
  lloc_accesses_sym = zzz_make_symbol ("lloc-accesses", -1);
  gloc_accesses_sym = zzz_make_symbol ("gloc-accesses", -1);
  tail_calls_sym = zzz_make_symbol ("tail-calls", -1);
  evaluate_calls_sym = zzz_make_symbol ("evaluate-calls", -1);
  closure_calls_sym = zzz_make_symbol ("closure-calls", -1);
  primitive_calls_sym = zzz_make_symbol ("primitive-calls", -1);
  syntactic_calls_sym = zzz_make_symbol ("syntactic-calls", -1);
  immediate_calls_sym = zzz_make_symbol ("immediate-calls", -1);

  zzz_define_function ("profile-stats", (zzz_prim_t) profile_stats,
		       argv_0_0_0);

  return RESULT_SUCCESS;
}
