/* amber_integer.pmc
 *  Copyright: same as Parrot.
 *  Overview:
 *     The Amber_INTEGER PMC, which implementes the Amber kernel class INTEGER
 */

#include "parrot/parrot.h"

static INTVAL class_CHARACTER;

pmclass Amber_INTEGER extends Integer extends Amber_DEFAULT does integer dynpmc group amber_kernel hll Amber maps Integer {

    void class_init() {
        if (pass) {
            /* Record the type-id of PMC Amber_CHARACTER */
            class_CHARACTER = Parrot_PMC_typenum(INTERP, "Amber_CHARACTER");
        }
    }

    PMC* neg (PMC* dest) {
        INTVAL a = -DYNSELF.get_integer();
        /* if (!dest)  --TODO: can we reinstate this if we generate n_neg instead of neg? */
            dest = pmc_new(
                INTERP, Parrot_get_ctx_HLL_type(INTERP, enum_class_Integer)
            );
        VTABLE_set_integer_native(INTERP, dest, a);
        return dest;
    }

/* non-vtable methods follow */

    METHOD PMC* abs() {
        /* XXX overflow for -maxint */
        PMC* result = pmc_new(
            INTERP, Parrot_get_ctx_HLL_type(INTERP, enum_class_Integer)
        );
        VTABLE_set_integer_native(INTERP, result, abs(PMC_int_val(SELF)));
        return result;
    }

    METHOD PMC* boolean() {
        PMC* result = pmc_new(
            INTERP, Parrot_get_ctx_HLL_type(INTERP, enum_class_Boolean)
        );
        VTABLE_set_bool(INTERP, result, PMC_int_val(SELF));
        return result;
    }

    METHOD PMC* character() {
        /* XXX consider Unicode */
        PMC* result = pmc_new(INTERP, class_CHARACTER);
        VTABLE_set_integer_native(INTERP, result, PMC_int_val(SELF));
        return result;
    }

    METHOD PMC* classname() {
        PMC* result = pmc_new(
            INTERP, Parrot_get_ctx_HLL_type(INTERP, enum_class_String)
        );
        VTABLE_set_string_native(
            INTERP, result, string_from_const_cstring(INTERP, "INTEGER", 7)
        );
        return result;
    }

    METHOD PMC* current() {
        return SELF;
    }

    METHOD PMC* integer() {
        PMC* result = pmc_new(
            INTERP, Parrot_get_ctx_HLL_type(INTERP, enum_class_Integer)
        );
        VTABLE_set_integer_native(INTERP, result, PMC_int_val(SELF));
        return result;
    }

}

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