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