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
);
}
}