// idbg - IJVM debugger.
// Copyright 2000 Tom Rothamel <tom-idbg@onegeek.org>
//
// This program 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 of the License, or
// (at your option) any later version.
//
// This program 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 program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  

/* -*-c++-*- */

%{
#include "idbg.h"
#include <malloc.h>
	
	void yyerror(char *);
	int yylex();
%}

%union {
	char *s;
	int i;
}

%token QUIT
%token REINIT
%token RUN
%token GO
%token STEP
%token NEXT
%token SHOW
%token DISASM
%token TRACE
%token STACK
%token VARS

%token PC

%token SET
%token STOP
%token page
%token quick
%token full
%token LOG

%token BREAK
%token DROP

%token <i> NUMBER
%token <s> METHODNAME
%token <s> NAME

%type <i> address

%% 

input:
| input statement
| input error
;

statement: QUIT {
	quit(0);
}
| REINIT {
	reinit();
}
| RUN {
	run();
}
| GO {
	go();
}
| STEP {
	execute(1);
}
| NEXT {
	next();
}
| SHOW {
	curses_show();
	getch();
	curses_hide();
}
| DISASM address {
	disasm($2, 0);
}
| DISASM address NUMBER {
	disasm($2, $3);
}
| SET page NUMBER {
	opage = $3;
}
| SET quick NUMBER {
	pp_quick = $3;
}
| SET full NUMBER {
	pp_full = $3;
}	
| SET DISASM NUMBER {
	pp_disasm = $3;
}
| SET LOG NAME {
	FILE *f;

	f = fopen($3, "w");
	olog(f);

	if (f) {
		oprintf("Logging has begun.\n");
	} else {
		oprintf("Not logging. (Bad filename?)\n");
	}

	free($3);
}
| STOP LOG {
	oprintf("Logging terminated.\n");
	olog(NULL);
}
| STACK {
	stack(-1);
}
| STACK NUMBER {
	stack($2);
}
| VARS {
	do_vars();
}
| TRACE {
	do_trace();
}
| BREAK address {
	add_breakpoint($2);
}
| DROP BREAK address {
	drop_breakpoint($3);
}
| SHOW BREAK {
	show_breakpoints();
}
;

address: NUMBER {
	$$ = $1;
}
| PC {
	$$ = vm->regs->pc;
}	
| PC '+' NUMBER {
	$$ = vm->regs->pc + $3;
}	
| PC '-' NUMBER {
	$$ = vm->regs->pc - $3;
}	
| METHODNAME {
	$$ = lookup_method_offset($1, -1);
	free($1);
}
| METHODNAME '+' NUMBER {
	$$ = lookup_method_offset($1, $3);
	free($1);
}
;
	

%%

void yyerror(char *s) {
	oprintf("%s\n", s);
}

void parse_string(char *s) {
	scan_string(s);
	yyparse();
}


	
	
