cvs -q diff -u
Index: classes/perlhash.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlhash.pmc,v
retrieving revision 1.69
diff -u -u -r1.69 perlhash.pmc
--- classes/perlhash.pmc	25 Feb 2004 09:13:15 -0000	1.69
+++ classes/perlhash.pmc	1 Apr 2004 22:14:06 -0000
@@ -476,10 +476,26 @@
 */
 
     void set_integer_keyed (PMC* key, INTVAL value) {
-        STRING* keystr = make_hash_key(INTERP, key);
-        PMC *val = pmc_new(interpreter, enum_class_PerlInt);
-        VTABLE_set_integer_native(INTERP, val, value);
-        hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+        STRING* keystr;
+        PMC* nextkey;
+        PMC* box;
+        PMC* val;
+
+        if (!key) return;
+        keystr = make_hash_key(INTERP, key);
+        nextkey = key_next(INTERP, key);
+        if (nextkey == NULL) {
+            val = pmc_new(interpreter, enum_class_PerlInt);
+            VTABLE_set_integer_native(INTERP, val, value);
+            hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+            return;
+        }
+        box = SELF.get_pmc_keyed_str(keystr);
+        if (box == NULL) {
+            /* autovivify an PerlHash */
+            box = pmc_new(INTERP, DYNSELF.type());
+        }
+        VTABLE_set_integer_keyed(INTERP, box, nextkey, value);
     }
 
 /*
@@ -505,10 +521,26 @@
 */
 
     void set_number_keyed (PMC* key, FLOATVAL value) {
-        STRING* keystr = make_hash_key(INTERP, key);
-        PMC *val = pmc_new(interpreter, enum_class_PerlNum);
-        PMC_num_val(val) = value;
-        hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+        STRING* keystr;
+        PMC* nextkey;
+        PMC* box;
+        PMC* val;
+
+        if (!key) return;
+        keystr = make_hash_key(INTERP, key);
+        nextkey = key_next(INTERP, key);
+        if (nextkey == NULL) {
+            val = pmc_new(interpreter, enum_class_PerlNum);
+            PMC_num_val(val) = value;
+            hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+            return;
+        }
+        box = SELF.get_pmc_keyed_str(keystr);
+        if (box == NULL) {
+            /* autovivify an PerlHash */
+            box = pmc_new(INTERP, DYNSELF.type());
+        }
+        VTABLE_set_number_keyed(INTERP, box, nextkey, value);
     }
 
 /*
@@ -562,10 +594,26 @@
 */
 
     void set_string_keyed (PMC* key, STRING* value) {
-        STRING* keystr = make_hash_key(INTERP, key);
-        PMC *val = pmc_new(interpreter, enum_class_PerlString);
-        VTABLE_set_string_native(INTERP, val, value);
-        hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+        STRING* keystr;
+        PMC* nextkey;
+        PMC* box;
+        PMC* val;
+
+        if (!key) return;
+        keystr = make_hash_key(INTERP, key);
+        nextkey = key_next(INTERP, key);
+        if (nextkey == NULL) {
+            val = pmc_new(interpreter, enum_class_PerlString);
+            VTABLE_set_string_native(INTERP, val, value);
+            hash_put(INTERP, PMC_struct_val(SELF), keystr, val);
+            return;
+        }
+        box = SELF.get_pmc_keyed_str(keystr);
+        if (box == NULL) {
+            /* autovivify an PerlHash */
+            box = pmc_new(INTERP, DYNSELF.type());
+        }
+        VTABLE_set_string_keyed(INTERP, box, nextkey, value);
     }
 
 /*
@@ -590,9 +638,25 @@
 
 */
 
-    void set_pmc_keyed (PMC* dest_key, PMC* value) {
-        STRING* keystr = make_hash_key(INTERP, dest_key);
-        hash_put(INTERP, PMC_struct_val(SELF), keystr, value);
+    void set_pmc_keyed (PMC* key, PMC* value) {
+        STRING* keystr;
+        PMC* nextkey;
+        PMC* box;
+        PMC* val;
+
+        if (!key) return;
+        keystr = make_hash_key(INTERP, key);
+        nextkey = key_next(INTERP, key);
+        if (nextkey == NULL) {
+            hash_put(INTERP, PMC_struct_val(SELF), keystr, value);
+            return;
+        }
+        box = SELF.get_pmc_keyed_str(keystr);
+        if (box == NULL) {
+            /* autovivify an PerlHash */
+            box = pmc_new(INTERP, DYNSELF.type());
+        }
+        VTABLE_set_pmc_keyed(INTERP, box, nextkey, value);
     }
 
 /*
Index: t/pmc/perlhash.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/perlhash.t,v
retrieving revision 1.41
diff -u -u -r1.41 perlhash.t
--- t/pmc/perlhash.t	8 Mar 2004 00:20:09 -0000	1.41
+++ t/pmc/perlhash.t	1 Apr 2004 22:14:23 -0000
@@ -1,4 +1,5 @@
 #! perl
+
 # Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
 # $Id: perlhash.t,v 1.41 2004/03/08 00:20:09 chromatic Exp $
 
@@ -18,9 +19,7 @@
 
 =cut
 
-# $Id: perlhash.t,v 1.41 2004/03/08 00:20:09 chromatic Exp $
-
-use Parrot::Test tests => 32;
+use Parrot::Test tests => 33;
 use Test::More;
 
 output_is(<<CODE, <<OUTPUT, "Initial PerlHash tests");
@@ -1013,3 +1012,131 @@
 U
 OUTPUT
 
+output_is(<< 'CODE', << 'OUTPUT', "Setting with compound keys");
+##PIR##
+.sub _main
+    .local pmc outer_hash
+    outer_hash = new PerlHash
+    .local pmc inner_hash
+    inner_hash = new PerlHash
+    .local pmc inner_array
+    inner_array = new PerlArray
+    .local string elem_string
+    .local int    elem_int
+    .local pmc    elem_pmc
+    .local num    elem_num
+
+    # setting and retrieving strings in an inner PerlArray
+    inner_array[128] = 'inner_array:128'
+    outer_hash['inner_array'] = inner_array
+    elem_string = outer_hash['inner_array';128]
+    print elem_string
+    print "\n" 
+    outer_hash['inner_array';128] = 'changed inner_array:128'
+    elem_string = outer_hash['inner_array';128]
+    print elem_string
+    print "\n" 
+
+    # setting and retrieving strings in an inner PerlHash
+    inner_hash['129'] = 'inner_hash:129'
+    outer_hash['inner_hash'] = inner_hash
+    elem_string = outer_hash['inner_hash';'129']
+    print elem_string
+    print "\n" 
+    outer_hash['inner_hash';'129'] = 'changed inner_hash:129'
+    elem_string = outer_hash['inner_hash';'129']
+    print elem_string
+    print "\n" 
+
+    # setting and retrieving integer in an inner PerlArray
+    inner_array[130] = 130
+    outer_hash['inner_array'] = inner_array
+    elem_int = outer_hash['inner_array';130]
+    print elem_int
+    print "\n" 
+    outer_hash['inner_array';130] = -130
+    elem_int = outer_hash['inner_array';130]
+    print elem_int
+    print "\n" 
+
+    # setting and retrieving integer in an inner PerlHash
+    inner_hash['131'] = 131
+    outer_hash['inner_hash'] = inner_hash
+    elem_int = outer_hash['inner_hash';'131']
+    print elem_int
+    print "\n" 
+    outer_hash['inner_hash';'131'] = -131
+    elem_int = outer_hash['inner_hash';'131']
+    print elem_int
+    print "\n" 
+
+    # setting and retrieving a PMC in an inner PerlArray
+    .local pmc in_pmc
+    in_pmc = new PerlString
+    in_pmc = 'inner_array:132'
+    inner_array[132] = in_pmc
+    outer_hash['inner_array'] = inner_array
+    elem_pmc = outer_hash['inner_array';132]
+    print elem_pmc
+    print "\n" 
+    in_pmc = 'changed inner_array:132'
+    outer_hash['inner_array';132] = in_pmc
+    elem_pmc = outer_hash['inner_array';132]
+    print elem_pmc
+    print "\n" 
+
+    # setting and retrieving a PMC in an inner PerlHash
+    in_pmc = 'inner_array:133'
+    inner_hash['133'] = in_pmc
+    outer_hash['inner_hash'] = inner_hash
+    elem_string = outer_hash['inner_hash';'133']
+    print elem_string
+    print "\n" 
+    in_pmc = 'changed inner_hash:133'
+    outer_hash['inner_hash';'133'] = in_pmc
+    elem_string = outer_hash['inner_hash';'133']
+    print elem_string
+    print "\n" 
+
+    # setting and retrieving a float in an inner PerlArray
+    inner_array[134] = 134.134
+    outer_hash['inner_array'] = inner_array
+    elem_num = outer_hash['inner_array';134]
+    print elem_num
+    print "\n" 
+    outer_hash['inner_array';134] = -134.134
+    elem_num = outer_hash['inner_array';134]
+    print elem_num
+    print "\n" 
+
+    # setting and retrieving a float in an inner PerlHash
+    inner_hash['135'] = 135.135
+    outer_hash['inner_hash'] = inner_hash
+    elem_num = outer_hash['inner_hash';'135']
+    print elem_num
+    print "\n" 
+    outer_hash['inner_hash';'135'] = -135.135
+    elem_num = outer_hash['inner_hash';'135']
+    print elem_num
+    print "\n" 
+
+    end
+.end
+CODE
+inner_array:128
+changed inner_array:128
+inner_hash:129
+changed inner_hash:129
+130
+-130
+131
+-131
+inner_array:132
+changed inner_array:132
+inner_array:133
+changed inner_hash:133
+134.134000
+-134.134000
+135.135000
+-135.135000
+OUTPUT
