/*
 * $Id: io.ops 47428 2010-06-06 08:32:34Z cotto $
 * Copyright (C) 2002-2008, Parrot Foundation.
** io.ops
*/

BEGIN_OPS_PREAMBLE
#include "../io/io_private.h"
END_OPS_PREAMBLE


=head1 NAME

io.ops - I/O Opcodes

=cut

=head1 DESCRIPTION

Parrot's IO API

When making changes to any ops file, run C<make bootstrap-ops> to regenerate
all generated ops files.

=cut

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

=head2 Parrot IO API Operations

=over 4

=cut

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

=item B<print>(in INT)

=item B<print>(in NUM)

=item B<print>(invar PMC)

=item B<print>(in STR)

Print $1 to standard output.

=cut

inline op print(in INT) :base_io {
    Parrot_io_printf(interp, INTVAL_FMT, (INTVAL)$1);
}

inline op print(in NUM) :base_io {
#ifdef PARROT_HAS_NEGATIVE_ZERO
    Parrot_io_printf(interp, FLOATVAL_FMT, $1);
#else
    /* Workaround for older msvcrt and openbsd. TT #313 */
    if (Parrot_is_nzero($1)) {
        Parrot_io_printf(interp, "-0");
    }
    else {
        Parrot_io_printf(interp, FLOATVAL_FMT, $1);
    }
#endif
}

op print(in STR) :base_io {
    STRING * const s = $1;
    if (s && Parrot_str_byte_length(interp, s))
        Parrot_io_putps(interp, _PIO_STDOUT(interp), s);
}

op print(invar PMC) :base_io {
    PMC * const p = $1;
    STRING * const s = (VTABLE_get_string(interp, p));
    if (s)
        Parrot_io_putps(interp, _PIO_STDOUT(interp), s);
}

=item B<say>(in INT)

=item B<say>(in NUM)

=item B<say>(invar PMC)

=item B<say>(in STR)

Print $1 to standard output with a trailing newline.

=cut

inline op say(in INT) :base_io {
    Parrot_io_printf(interp, INTVAL_FMT "\n", (INTVAL)$1);
}

inline op say(in NUM) :base_io {
#ifdef PARROT_HAS_NEGATIVE_ZERO
    Parrot_io_printf(interp, FLOATVAL_FMT "\n", $1);
#else
    /* Workaround for older msvcrt and openbsd. TT #313 */
    if (Parrot_is_nzero($1)) {
        Parrot_io_printf(interp, "-0\n");
    }
    else {
        Parrot_io_printf(interp, FLOATVAL_FMT "\n", $1);
    }
#endif
}

op say(in STR) :base_io {
    STRING * const s = $1;
    if (s && Parrot_str_byte_length(interp, s))
        Parrot_io_putps(interp, _PIO_STDOUT(interp), s);
    Parrot_io_putps(interp, _PIO_STDOUT(interp), Parrot_str_new_constant(interp, "\n"));
}

op say(invar PMC) :base_io {
    PMC * const p = $1;

    if (PMC_IS_NULL(p)) {
        opcode_t *handler = Parrot_ex_throw_from_op_args(interp, expr NEXT(),
             EXCEPTION_UNEXPECTED_NULL,
            "Null PMC in say");
        goto ADDRESS(handler);
    }
    else {
        STRING * const s = VTABLE_get_string(interp, p);
        if (s)
            Parrot_io_putps(interp, _PIO_STDOUT(interp), s);
        Parrot_io_putps(interp, _PIO_STDOUT(interp), Parrot_str_new_constant(interp, "\n"));
    }
}




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

=item B<print>(invar PMC, in INT)

=item B<print>(invar PMC, in NUM)

=item B<print>(invar PMC, in STR)

=item B<print>(invar PMC, invar PMC)

Print $2 on the IO stream object $1.

=cut

op print(invar PMC, in INT) :base_io {
    if ($1) {
        STRING * const s = Parrot_str_from_int(interp, $2);
        Parrot_io_putps(interp, $1, s);
    }
}

op print(invar PMC, in NUM) :base_io {
    if ($1) {
        STRING * const s = Parrot_sprintf_c(interp, FLOATVAL_FMT, $2);
        Parrot_io_putps(interp, $1, s);
    }
}

op print(invar PMC, in STR) :base_io {
    if ($2 && $1) {
        Parrot_io_putps(interp, $1, $2);
    }
}

op print(invar PMC, invar PMC) :base_io {
    if ($2 && $1) {
        STRING * const s = VTABLE_get_string(interp, $2);
        Parrot_io_putps(interp, $1, s);
    }
}

=item B<getstdin>(out PMC)

Create a new ParrotIO object for the stdin file descriptor and
store it in $1

=item B<getstdout>(out PMC)

Create a new ParrotIO object for the stdout file descriptor and
store it in $1

=item B<getstderr>(out PMC)

Create a new ParrotIO object for the stderr file descriptor and
store it in $1

=cut

inline op getstdin(out PMC) :base_io {
    $1 = _PIO_STDIN(interp);
}

inline op getstdout(out PMC) :base_io {
    $1 = _PIO_STDOUT(interp);
}

inline op getstderr(out PMC) :base_io {
    $1 = _PIO_STDERR(interp);
}

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

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
