/*
Copyright (C) 2005-2006, The Perl Foundation.
$Id: luaboolean.pmc 17096 2007-02-20 20:20:48Z paultcochrane $

=head1 NAME

pmc/luaboolean.pmc - Lua Boolean

=head1 DESCRIPTION

C<LuaBoolean> extends C<LuaAny> to provide a class with the behaviour of
the Lua C<Boolean> type.

The value is stored as an Integer.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

static STRING *false_string;
static STRING *true_string;
static STRING *luaboolean_name;
extern INTVAL dynpmc_LuaBoolean;

pmclass LuaBoolean
    extends LuaAny
    does scalar
    does boolean
    does integer
    dynpmc
    group lua_group
    hll Lua
    maps Boolean {

/* Class initialization. Caches constant strings that will be used later.
*/
    void class_init() {
        if (pass) {
            false_string = const_string(INTERP, "false");
            true_string = const_string(INTERP, "true");
            luaboolean_name = const_string(INTERP, "boolean");
        }
    }

/*

=item C<void init()>

Initializes the Boolean with a default value of C<false>.

=cut

*/
    void init () {
        PMC_int_val(SELF) = 0;
    }

/*

=item C<PMC new_from_string(STRING *rep)>

Class method to construct an Boolean from the string representation C<rep>.

=cut

*/
    PMC* new_from_string (STRING *rep, INTVAL flags) {
        INTVAL type;
        PMC *res;

        type = SELF->vtable->base_type;
        if (flags & PObj_constant_FLAG)
            res = constant_pmc_new(INTERP, type);
        else
            res = pmc_new(INTERP, type);
        PMC_int_val(res) = (string_to_int(INTERP, rep) != 0);
        return res;
    }

/*

=item C<void morph(INTVAL type)>

Morphs the scalar to the specified type.

=cut

*/
    void morph (INTVAL type) {
        if (SELF->vtable->base_type == type)
            return;
        pmc_reuse(INTERP, SELF, type, 0);
    }

/*

=item C<STRING* name()>

Return the string "boolean".

=cut

*/
    STRING* name () {
        return luaboolean_name;
    }

/*

=item C<PMC *clone()>

Creates and returns a clone of the scalar.

=cut

*/
    PMC* clone () {
        PMC* dest = pmc_new(INTERP, SELF->vtable->base_type);
        memcpy(&PMC_union(dest), &PMC_union(SELF), sizeof(UnionVal));
        return dest;
    }

/*

=item C<INTVAL get_integer()>

Returns the integer value of the Boolean.

=cut

*/
    INTVAL get_integer () {
        return PMC_int_val(SELF);
    }

/*

=item C<STRING* get_string ()>

Return the string "true" or "false".

=cut

*/
    STRING* get_string () {
        if (PMC_int_val(SELF))
            return true_string;
        else
            return false_string;
    }


/*

=item C<INTVAL get_bool ()>

Returns the boolean value of the Boolean.

=cut

*/
    INTVAL get_bool () {
        return PMC_int_val(SELF) ? 1 : 0;
    }

/*

=item C<void set_integer_native (INTVAL value)>

=item C<void set_bool (INTVAL value)>

=cut

*/
    void set_integer_native (INTVAL value) {
        PMC_int_val(SELF) = (value != 0);
    }

    void set_bool (INTVAL value) {
        PMC_int_val(SELF) = (value != 0);
    }

/*

=item C<void freeze(visit_info *info)>

Used to archive the boolean.

=cut

*/
    void freeze (visit_info *info) {
        IMAGE_IO *io = info->image_io;
        SUPER(info);
        VTABLE_push_integer(INTERP, io, PMC_int_val(SELF));
    }

/*

=item C<void thaw(visit_info *info)>

Used to unarchive the boolean.

=cut

*/
    void thaw (visit_info *info) {
        IMAGE_IO *io = info->image_io;
        SUPER(info);
        if (info->extra_flags == EXTRA_IS_NULL)
            PMC_int_val(SELF) = VTABLE_shift_integer(INTERP, io);
    }

/*

=back

=head2 non-Vtable Methods

=over 4

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

=cut

*/
    INTVAL is_equal (PMC* value) {
MMD_LuaBoolean: {
            return (INTVAL)(PMC_int_val(SELF) ==
                VTABLE_get_integer(INTERP, value));
        }
MMD_DEFAULT: {
            return (INTVAL)0;
        }
    }

/*

=back

=head2 Specific Methods

=over 4

=item C<PMC* rawequal (PMC* value)>

=cut

*/
    METHOD PMC* rawequal (PMC* value) {
        PMC *retval;

        retval = pmc_new(INTERP, dynpmc_LuaBoolean);
        if (SELF->vtable->base_type == value->vtable->base_type
         && PMC_int_val(SELF) == PMC_int_val(value))
            PMC_int_val(retval) = 1;
        else
            PMC_int_val(retval) = 0;
        return retval;
    }

}

/*

=back

=head1 AUTHORS

Francois Perrad.

Klaas-Jan Stol.

=cut

*/


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