/*
Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
$Id: pylist.pmc,v 1.69 2004/07/13 14:09:23 leo Exp $

=head1 NAME

classes/pylist.pmc - Python List

=head1 DESCRIPTION

These are the vtable functions for the PyList base class

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

/* cache of classes referenced */
static INTVAL dynclass_PyInt;
static INTVAL dynclass_PyNone;
static INTVAL dynclass_PyString;

pmclass PyList extends PyObject need_ext does array dynpmc group python_group {

/*

=item C<void class_init()>

Class initialization. Caches the type id of various PMCs because
they will be used frequently here.

=cut

*/

    void class_init() {
        if (pass) {
            dynclass_PyInt     = Parrot_PMC_typenum(INTERP, "PyInt");
            dynclass_PyNone    = Parrot_PMC_typenum(INTERP, "PyNone");
            dynclass_PyString  = Parrot_PMC_typenum(INTERP, "PyString");
        }
    }

/*

=item C<void init()>

Initializes the PMC by calling the underlying C<list_new()> function.

=cut

*/

    void init () {
        list_pmc_new(INTERP, SELF);
        PObj_custom_mark_SET(SELF);
    }

/*

=item C<INTVAL elements()>

Returns the number of elements in the array.

=cut

*/

    INTVAL elements () {
        return ((List *) PMC_data(SELF))->length;
    }

/*

=item C<INTVAL get_integer()>

Returns the number of elements in the array.

=cut

*/

    INTVAL get_integer () {
        return DYNSELF.elements();
    }

/*

=item C<PMC* get_pmc_keyed(PMC* key)>

Returns the PMC value of the element at index C<key>.

=cut

*/

    PMC* get_pmc_keyed (PMC* key) {
        INTVAL ix = key_integer(INTERP, key);
        return SELF.get_pmc_keyed_int(ix);
    }

/*

=item C<PMC* get_pmc_keyed_int(INTVAL key)>

Returns the PMC value of the element at index C<key>.

=cut

*/

    PMC* get_pmc_keyed_int (INTVAL key) {
        List *list = (List *)PMC_data(SELF);
        PMC *ret = list_get(INTERP, list, key, enum_type_PMC);

        if (ret == (void*) -1)
            /* XXX throw IndexError: list index out of range */ ;
        else {
            ret = *(PMC**) ret;
            if (ret == NULL)
                ret = pmc_new(interpreter, dynclass_PyNone);
        }

        return ret;
    }

/*

=item C<STRING *get_string()>

Returns the list as a string

=cut

*/

    STRING* get_string () {
        STRING *res, *s;
        INTVAL j, n;
        PMC *val;

        res = string_from_cstring(INTERP, "[", 0);
        n = VTABLE_elements(INTERP, SELF);
        for (j = 0; j < n; ++j) {
            STRING *vals;
            val = SELF.get_pmc_keyed_int(j);
            REG_INT(3) = 0;
            vals = VTABLE_get_repr(INTERP, val);
            res = string_append(INTERP, res, vals, 0);
            if (j < n - 1)
                res = string_append(INTERP, res,
                        const_string(INTERP, ", "), 0);
        }
        res = string_append(INTERP, res,
                    const_string(INTERP, "]"), 0);
        return res;
    }

/*

=item C<void push_integer (INTVAL value)>

Extends the array by adding an element of value C<value> to the end of
the array.

=cut

*/

    void push_integer (INTVAL value) {
        INTVAL nextix = DYNSELF.elements();
        DYNSELF.set_integer_keyed_int(nextix, value);
    }

/*

=item C<void push_pmc (PMC* value)>

Extends the array by adding an element of value C<*value> to the end of
the array.

=cut

*/

    void push_pmc (PMC* value) {
        INTVAL nextix = DYNSELF.elements();
        DYNSELF.set_pmc_keyed_int(nextix, value);
    }

/*

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

Extends the array by adding an element of value C<*value> to the end of
the array.

=cut

*/

    void push_string (STRING* value) {
        INTVAL nextix = DYNSELF.elements();
        DYNSELF.set_string_keyed_int(nextix, value);
    }

/*

=item C<void set_integer_keyed_int (INTVAL key, INTVAL value)>

Sets the integer value of the PMC at element C<key> to C<value>.

=cut

*/

    void set_integer_keyed_int (INTVAL key, INTVAL value) {
        PMC *src = pmc_new_noinit(INTERP, dynclass_PyInt);
        PMC_int_val(src) = value;
        list_assign(INTERP, (List *) PMC_data(SELF), key, src, enum_type_PMC);
    }

/*

=item C<void set_integer_native(INTVAL size)>

Sets the length of the array to C<size>.

=cut

*/

    void set_integer_native (INTVAL size) {
        list_set_length(INTERP, (List *) PMC_data(SELF) ,size);
    }

/*

=item C<void set_pmc_keyed(PMC* key)>

Sets the PMC at element C<key> to C<*value>.

=cut

*/

    void set_pmc_keyed (PMC* key, PMC* value) {
        INTVAL ix = key_integer(INTERP, key);
        SELF.set_pmc_keyed_int(ix, value);
    }

/*

=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>

Assigns C<*src> to the array at index C<key>.

=cut

*/

    void set_pmc_keyed_int (INTVAL key, PMC* src) {
        list_assign(INTERP, (List *) PMC_data(SELF), key, src, enum_type_PMC);
    }

/*

=item C<void set_string_keyed_int(INTVAL key, STRING* value)>

Sets the string value of the PMC at element C<key> to C<value>.

=cut

*/

    void set_string_keyed_int (INTVAL key, STRING* value) {
        PMC *src = pmc_new_noinit(INTERP, dynclass_PyString);
        VTABLE_set_string_native(INTERP, src, value);
        list_assign(INTERP, (List *) PMC_data(SELF), key, src, enum_type_PMC);
    }

/*

=back

=cut

*/

}

/*
 * Local variables:
 * c-indentation-style: bsd
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 *
 * vim: expandtab shiftwidth=4:
*/
