/*
Copyright (C) 2001-2006, The Perl Foundation.
$Id: perlstring.pmc 16836 2007-01-30 04:30:52Z coke $

=head1 NAME

src/dynpmc/perlstring.pmc - Perl String

=head1 DESCRIPTION

C<PerlString> extends C<String> to provide Perl-specific string behaviour.
Note that the C<morph> method comes from C<PerlScalar>,
not from C<String>.

=head2 Methods

=over 4

=cut

*/

#include "parrot/parrot.h"

void Parrot_perlscalar_morph(Interp* , PMC* pmc, INTVAL type);

pmclass PerlString
    extends String
    does string
    does scalar
    dynpmc
    group perl_group
    hll Perl
    maps String {

/*

=item C<INTVAL get_integer()>

Returns the integer representation of the string by converting to float first.
See t/pmc/perlstring_13    set P0, "1.23e2" ; set I0, P0

=cut

*/
    INTVAL get_integer() {
        double f = DYNSELF.get_number();
        return (INTVAL)f;
    }

/*

=item C<STRING* get_repr()>

Returns pythons string repr (w/o any escaping, just single quotes around)

=cut

*/

    STRING* get_repr() {
        STRING *start, *s, *q, *repr;
        q = const_string(INTERP, "'");
        s = DYNSELF.get_string();
        if (PObj_get_FLAGS(s) & PObj_private7_FLAG)
            start = const_string(INTERP, "u'");
        else
            start = q;
        repr = string_copy(INTERP, start);
        repr = string_append(INTERP, repr, s);
        repr = string_append(INTERP, repr, q);
        return repr;
    }

/*

=item C<void set_integer_native(INTVAL value)>

Morphs the string to a C<PerlInt> and sets its value to C<value>.

=cut

*/

    void set_integer_native(INTVAL value) {
        INTVAL dynpmc_PerlInt;

        dynpmc_PerlInt = pmc_type(interp,
            string_from_const_cstring(interp, "PerlInt", 0));
        DYNSELF.morph(dynpmc_PerlInt);
        DYNSELF.set_integer_native(value);
    }

/*

=item C<void set_number_native(FLOATVAL value)>

Morphs the string to a C<PerlNum> and sets its value to C<value>.

=cut

*/

    void set_number_native(FLOATVAL value) {
        INTVAL dynpmc_PerlNum;

        dynpmc_PerlNum = pmc_type(interp,
            string_from_const_cstring(interp, "PerlNum", 0));
        DYNSELF.morph(dynpmc_PerlNum);
        DYNSELF.set_number_native(value);
    }

/*

=item C<void morph(INTVAL type)>

Morphs the C<PerlString> to the specified type.

=cut

*/

    void morph(INTVAL type) {
        perlscalar.SELF.morph(type);
    }

/*

=item C<void increment()>

=item C<void decrement()>

These two methods are partially implemented. They should provide
Perl 5 like string increment/decrement.

=cut

*/

    void increment() {
        STRING* s = PMC_str_val(SELF);
        PMC_str_val(SELF) = string_increment(INTERP, s);
    }

    void decrement() {
        INTVAL i = VTABLE_get_integer(INTERP, SELF);
        VTABLE_set_integer_native(INTERP, SELF, i - 1);
    }


/*

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

Returns the string value for C<SELF[key]>.

=cut

*/

    PMC* get_pmc_keyed(PMC* key) {
        STRING    *s;
        PMC       *ret;
        INTVAL     dynpmc_PerlString;

        s = PMC_str_val(SELF);
        dynpmc_PerlString = pmc_type(interp,
            string_from_const_cstring(interp, "PerlString", 0));
        ret = pmc_new_noinit(INTERP, dynpmc_PerlString);
        PMC_str_val(ret) = string_substr(INTERP, s,
                key_integer(INTERP,key), 1, NULL, 0);
        PObj_custom_mark_SET(ret);

        return ret;
    }

}

/*

=back

=cut

*/

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