/*
** debug.ops
*/

VERSION = PARROT_VERSION;

=head1 NAME

debug.ops

=cut

=head1 DESCRIPTION

Parrot debuger

=cut

=head1 HISTORY

Initial version by Daniel Grunblatt on 2002.5.19

=cut

###############################################################################

=head2 Parrot debug operations

=over 4

=cut

########################################

=item B<debug_init>()

Init the parrot debugger, must be called before any other debug op.

=cut

op debug_init() {
    PDB_t *pdb;

    if (!(interpreter->pdb)) {
        pdb = (PDB_t *)mem_sys_allocate_zeroed(sizeof(PDB_t));

        interpreter->pdb = pdb;
        pdb->cur_opcode = interpreter->code->byte_code;
        pdb->state |= PDB_RUNNING;
    }

    goto NEXT();
}

########################################

=item B<debug_load>(inconst STR)

Load a Parrot source file for the current program.

=cut

op debug_load(inconst STR) {
    const char *f;

    if (!(interpreter->pdb->state & PDB_BREAK)) {
        f = string_to_cstring(interpreter,($1));
        PDB_load_source(interpreter,f);
    }

    goto NEXT();
}

########################################

=item B<debug_break>()

Break execution and drop into the debugger.
If we are already into the debugger and is the first time we are
called set a breakpoint.

When you re run/continue the program begin debugged it will pay 
no attention to the debug ops. 

TODO: clone the interpreter to allow people to play into the 
debugger and then continue the normal execution of the program.

=cut

op debug_break() {
    const char *command;

    if (!(interpreter->pdb->state & PDB_BREAK)) {
        interpreter->pdb->state |= PDB_BREAK;
        interpreter->pdb->state |= PDB_STOPPED;
        interpreter->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; 
        PDB_set_break(interpreter,NULL);
        while (!(interpreter->pdb->state & PDB_EXIT)) {
            PDB_get_command(interpreter);
            command = interpreter->pdb->cur_command;
            PDB_run_command(interpreter,command);
        }
        /* FIXME this is not ok */
        exit(0);
    }
    interpreter->pdb->cur_opcode = (opcode_t *)cur_opcode + 1; 
    PDB_set_break(interpreter,NULL);

    goto NEXT();
} 

########################################

=item B<debug_print>()

Print all the parrot registers at once.

=cut

op debug_print() {
    if (!(interpreter->pdb->state & PDB_BREAK)) {
        PDB_print_int(interpreter, &interpreter->int_reg, -1);
        PDB_print_num(interpreter, &interpreter->num_reg, -1);
        PDB_print_string(interpreter,&interpreter->string_reg, -1);
        PDB_print_pmc(interpreter,&interpreter->pmc_reg, -1, NULL);
    }
    goto NEXT();
}
    
########################################

=back

=cut