/*
Copyright (C) 2004 - 2008, The Perl Foundation.
$Id: /mirror/trunk/src/pmc/undef.pmc 35549 2009-01-14T06:12:35.790948Z cotto  $

=head1 NAME

src/pmc/undef.pmc - Generic undefined value

=head1 DESCRIPTION

This is Parrot's generic undef type. This PMC has no defined value.
It returns a numeric value of 0, a boolean of false, and an empty string.
When assigned a number, integer, or string it morphs to a Number,
Integer, or String PMC respectively, and when assigned a generic PMC
it morphs into a PMC of the passed-in type and does a same-type assignment
from there.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"
#define UNDEF_STRING_CLASS enum_class_String

pmclass Undef no_ro {

/*

=item C<void set_pmc(PMC *other)>

Sets the current PMC to C<*other> by first changing the current PMC to the
appropriate type.

=cut

*/

    VTABLE void set_pmc(PMC *other) {
        VTABLE_morph(INTERP, SELF, enum_class_Ref);
        VTABLE_set_pmc(INTERP, SELF, other);
    }

/*

=item C<void assign_pmc(PMC *other)>

Assigns the PMC to the value of C<*other> by first changing the PMC to the
appropriate type.

=cut

*/

    VTABLE void assign_pmc(PMC *other) {
        if (!PObj_is_object_TEST(other))
            VTABLE_morph(INTERP, SELF, other->vtable->base_type);

        /* don't want to call set_pmc if we're assigning an Undef to an Undef */
        if (other->vtable->base_type != enum_class_Undef)
            VTABLE_set_pmc(INTERP, SELF, other);
    }


/*

=item C<INTVAL get_integer()>

Returns 0.

=cut

*/

    VTABLE INTVAL get_integer() {
        return 0;
    }

/*

=item C<INTVAL defined()>

Returns 0.

=cut

*/

    VTABLE INTVAL defined() {
        return 0;
    }

/*

=item C<void set_integer_native(INTVAL value)>

Morphs the current PMC to an C<Integer> and sets the value from C<value>.

=cut

*/

    VTABLE void set_integer_native(INTVAL value) {
        VTABLE_morph(INTERP, SELF, enum_class_Integer);
        VTABLE_set_integer_native(INTERP, SELF, value);
    }

/*

=item C<FLOATVAL get_number()>

Returns 0.0.

=cut

*/

    VTABLE FLOATVAL get_number() {
        return 0.0;
    }

/*

=item C<void set_number_native(FLOATVAL value)>

Morphs the current PMC to a C<Float> and sets the value from C<value>.

=cut

*/

    VTABLE void set_number_native(FLOATVAL value) {
        VTABLE_morph(INTERP, SELF, enum_class_Float);
        VTABLE_set_number_native(INTERP, SELF, value);
    }

/*

=item C<STRING *get_string()>

Returns an empty string.

=cut

*/

    VTABLE STRING *get_string() {
        return string_make_empty(INTERP, enum_stringrep_one, 0);
    }

/*

=item C<void set_string_native(STRING *value)>

Morphs the current PMC to a C<String> and sets the value from C<value>.

=cut

*/

    VTABLE void set_string_native(STRING *value) {
        VTABLE_morph(INTERP, SELF, UNDEF_STRING_CLASS);
        VTABLE_set_string_native(INTERP, SELF, value);
    }

/*

=item C<INTVAL get_bool()>

Returns 0.

=cut

*/

    VTABLE INTVAL get_bool() {
        return 0;
    }

/*

=item C<void share()>

Unknown. (TODO)

=cut

*/

    VTABLE void share() {
        /* see src/pmc/integer.pmc */
    }

/*

=item C<PMC *share_ro()>

Unknown. (TODO)

=cut

*/

    VTABLE PMC *share_ro() {
        if (PObj_is_PMC_shared_TEST(SELF))
            return SELF;
        else
            return pt_shared_fixup(INTERP, SELF);
    }

/*

=item C<PMC *clone()>

Clones the current Undef PMC.

=cut

*/

    VTABLE PMC *clone() {
        return pmc_new(INTERP, SELF->vtable->base_type);
    }

/*

=item C<INTVAL is_equal(PMC *value)>

Returns 1 if the C<*value> is an Undef PMC, 0 otherwise.

=cut

*/

    MULTI INTVAL is_equal(Undef value) {
        return 1;
    }

    MULTI INTVAL is_equal(DEFAULT value) {
        return 0;
    }
}

/*

=back

=cut

*/


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