On Fri, 2004-01-23 at 06:16, Dan Sugalski wrote:

> Hang it off the cache slot, and mark the cache as a buffer with the 
> data you need in it. (That's how I'd do it, at least)

Something like this?

I'm having odd troubles with "Key not an integer!", which indicates I'm
doing something wrong.  Still, it *looks* fairly solid, at least for
getting and setting integers and floats.

Any suggestions?

-- c


.include "datatypes.pasm"

.sub _main
        new $P1, .PerlArray
        print "at 1\n"
        push $P1, .DATATYPE_INT16
        push $P1, 0
        push $P1, 0
        push $P1, 'x'
        print "at 2\n"
        push $P1, .DATATYPE_INT16
        push $P1, 0
        push $P1, 0
        push $P1, 'y'

        print "at 3\n"
        new $P2, .HashlikeStruct
        $P2 = $P1

        print "at 4\n"
        set $I0, 0
        sizeof $I1, .DATATYPE_INT16
        add $I0, $I1
        add $I0, $I1

        set $P1, $I0

        print "at 5\n"
        set $I0, 2
        set $S0, "x"
        set $P2[$S0], $I0

        print "at 6\n"
        set $P2["y"], 16

        print "at 7\n"
        set $I2, $P1[0]
        set $I3, $P1[1]

        print "\nx: "
        print $I2

        print "\ny: "
        print $I3

        print "\n"
        end
.end
#include "parrot/parrot.h"
#include "parrot/vtable.h"

pmclass HashlikeStruct extends UnManagedStruct need_ext does hash
{
        void init ()
        {
                PMC_ptr2p(SELF)     = NULL;
                SELF->cache.pmc_val = pmc_new( interpreter, enum_class_PerlHash );
        }

        void set_pmc (PMC* value)
        {
                size_t i;
                size_t n            = (size_t)VTABLE_elements(interpreter, value);
                size_t total_offset = 0;

                if (n % 4)
                        internal_exception( 1, "Illegal initializer for 
hashlikestruct" );

                PMC_ptr2p(SELF) = value;

                for ( i = 0; i < n; i += 4 )
                {
                        int     type, count, offset;
                        STRING* name;

                        type   = (int)VTABLE_get_integer_keyed_int(interpreter, value, 
i);
                        count  = (int)VTABLE_get_integer_keyed_int(interpreter, value, 
i+1);
                        offset = (int)VTABLE_get_integer_keyed_int(interpreter, value, 
i+2);
                        name   =      VTABLE_get_string_keyed_int(interpreter,  value, 
i+3);

                        if (type < enum_first_type || type >= enum_last_type)
                                internal_exception(1, "Illegal type in initializer for 
struct");

                        if (count <= 0)
                        {
                                count = 1;
                                VTABLE_set_integer_keyed_int(interpreter, value, i+1, 
count);
                        }

                        if (offset <= 0)
                        {
                                offset = total_offset;
                                VTABLE_set_integer_keyed_int(interpreter, value, i+2, 
offset);
                        }
                        else
                        {
                                total_offset  = offset;
                                total_offset += count * 
(data_types[type-enum_first_type].size);
                                if (i == n - 3 &&
                                    pmc->vtable->base_type == enum_class_ManagedStruct)
                                                
DYNSELF.set_integer_native(total_offset);
                        }

                        if (string_compute_strlen( name ) > 0)
                        {
                                VTABLE_set_integer_keyed_str(
                                        interpreter, SELF->cache.pmc_val, name, offset
                                );
                        }
                }
        }

        INTVAL get_integer_keyed_str (STRING* key)
        {
                INTVAL offset, value;
                offset = VTABLE_get_integer_keyed_str(
                                     interpreter, SELF->cache.pmc_val, key );
                value  = DYNSELF.get_integer_keyed_int( offset );

                return value;
        }

        void set_integer_keyed_str (STRING* key, INTVAL value)
        {
                INTVAL offset;
                offset = VTABLE_get_integer_keyed_str(
                                interpreter, SELF->cache.pmc_val, key );

                VTABLE_set_integer_keyed_int( interpreter, SELF, offset, value );
        }

        FLOATVAL get_number_keyed_str (STRING* key)
        {
                return VTABLE_get_number_keyed_int( interpreter, SELF,
                        VTABLE_get_integer_keyed_str(interpreter, SELF->cache.pmc_val, 
key)
                );
        }

        void set_number_keyed_str (STRING* key, FLOATVAL value)
        {
                VTABLE_set_number_keyed_int( interpreter, SELF,
                        VTABLE_get_integer_keyed_str(interpreter, SELF->cache.pmc_val, 
key),
                        value
                );
        }
}

Reply via email to