The implementation of the methods key_* in keys.c imposed
to the PMCs to be of type Key.  I don't' see the interest
for atomic keys that could be mere PMCs.

This concretely means that one can write the following and save a
intermediate register:

  P3 = PO[P1]

instead of:

  P3 = new P2, .Key
  P2 = P1
  P3 = PO[P1]

or instead of:

  S0 = P1
  P3 = P0[S0]  # if the key is used as a string


Patch includes code and test.
Affects src/key.c and t/pmc/key.t.

--
 stef

--- src/key.c.old       2004-01-27 01:01:16.000000000 +0100
+++ src/key.c   2004-02-09 18:11:47.000000000 +0100
@@ -283,21 +283,27 @@
 key_integer(struct Parrot_Interp *interpreter, PMC *key)
 {
     PMC *reg;
+    int flags      =   PObj_get_FLAGS(key);
+    int key_flags  =   flags & KEY_type_FLAGS;
 
-    switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
-    case KEY_integer_FLAG:
-        return key->cache.int_val;
-    case KEY_integer_FLAG | KEY_register_FLAG:
-        return interpreter->int_reg.registers[key->cache.int_val];
-    case KEY_pmc_FLAG:
-        return VTABLE_get_integer(interpreter,
-                                                       key->cache.pmc_val);
-    case KEY_pmc_FLAG | KEY_register_FLAG:
-        reg = interpreter->pmc_reg.registers[key->cache.int_val];
-        return VTABLE_get_integer(interpreter, reg);
-    default:
-        internal_exception(INVALID_OPERATION, "Key not an integer!\n");
-        return 0;
+    if(key_flags) {
+        switch (key_flags) {
+        case KEY_integer_FLAG:
+            return key->cache.int_val;
+        case KEY_integer_FLAG | KEY_register_FLAG:
+            return interpreter->int_reg.registers[key->cache.int_val];
+        case KEY_pmc_FLAG:
+            return VTABLE_get_integer(interpreter,
+                                                           key->cache.pmc_val);
+        case KEY_pmc_FLAG | KEY_register_FLAG:
+            reg = interpreter->pmc_reg.registers[key->cache.int_val];
+            return VTABLE_get_integer(interpreter, reg);
+        default:
+            internal_exception(INVALID_OPERATION, "Key not an integer!\n");
+            return 0;
+        }
+    } else {
+        return VTABLE_get_integer(interpreter, key);
     }
 }
 
@@ -313,22 +319,29 @@
 FLOATVAL
 key_number(struct Parrot_Interp *interpreter, PMC *key)
 {
+
     PMC *reg;
+    int flags      =   PObj_get_FLAGS(key);
+    int key_flags  =   flags & KEY_type_FLAGS;
 
-    switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
-    case KEY_number_FLAG:
-        return key->cache.num_val;
-    case KEY_number_FLAG | KEY_register_FLAG:
-        return interpreter->num_reg.registers[key->cache.int_val];
-    case KEY_pmc_FLAG:
-        return VTABLE_get_number(interpreter,
-                                                      key->cache.pmc_val);
-    case KEY_pmc_FLAG | KEY_register_FLAG:
-        reg = interpreter->pmc_reg.registers[key->cache.int_val];
-        return VTABLE_get_number(interpreter, reg);
-    default:
-        internal_exception(INVALID_OPERATION, "Key not a number!\n");
-        return 0;
+    if (key_flags) {
+        switch (key_flags) {
+        case KEY_number_FLAG:
+            return key->cache.num_val;
+        case KEY_number_FLAG | KEY_register_FLAG:
+            return interpreter->num_reg.registers[key->cache.int_val];
+        case KEY_pmc_FLAG:
+            return VTABLE_get_number(interpreter,
+                                                          key->cache.pmc_val);
+        case KEY_pmc_FLAG | KEY_register_FLAG:
+            reg = interpreter->pmc_reg.registers[key->cache.int_val];
+            return VTABLE_get_number(interpreter, reg);
+        default:
+            internal_exception(INVALID_OPERATION, "Key not a number!\n");
+            return 0;
+        }
+    } else {
+        return VTABLE_get_number(interpreter, key);
     }
 }
 
@@ -345,21 +358,29 @@
 key_string(struct Parrot_Interp *interpreter, PMC *key)
 {
     PMC *reg;
+    int flags      =   PObj_get_FLAGS(key);
+    int key_flags  =   flags & KEY_type_FLAGS;
 
-    switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
-    case KEY_string_FLAG:
-        return key->cache.string_val;
-    case KEY_string_FLAG | KEY_register_FLAG:
-        return interpreter->string_reg.registers[key->cache.int_val];
-    case KEY_pmc_FLAG:
-        return VTABLE_get_string(interpreter,
-                                                      key->cache.pmc_val);
-    case KEY_pmc_FLAG | KEY_register_FLAG:
-        reg = interpreter->pmc_reg.registers[key->cache.int_val];
-        return VTABLE_get_string(interpreter, reg);
-    default:
-        internal_exception(INVALID_OPERATION, "Key not a string!\n");
-        return 0;
+    if (key_flags) {
+        switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+        case KEY_integer_FLAG:
+            string_from_int(interpreter, key->cache.int_val);
+        case KEY_string_FLAG:
+            return key->cache.string_val;
+        case KEY_string_FLAG | KEY_register_FLAG:
+            return interpreter->string_reg.registers[key->cache.int_val];
+        case KEY_pmc_FLAG:
+            return VTABLE_get_string(interpreter,
+                                                          key->cache.pmc_val);
+        case KEY_pmc_FLAG | KEY_register_FLAG:
+            reg = interpreter->pmc_reg.registers[key->cache.int_val];
+            return VTABLE_get_string(interpreter, reg);
+        default:
+            internal_exception(INVALID_OPERATION, "Key not a string!\n");
+            return 0;
+        }
+    } else {
+        return VTABLE_get_string(interpreter, key);
     }
 }
 
@@ -403,7 +424,10 @@
 PMC *
 key_next(struct Parrot_Interp *interpreter, PMC *key)
 {
-    return PMC_data(key);
+    if (PObj_get_FLAGS(key) & KEY_type_FLAGS)
+        return PMC_data(key);
+    return (PMC*) NULL;
+
 }
 
 /*

--- t/pmc/key.t.old     2004-02-09 19:41:22.000000000 +0100
+++ t/pmc/key.t 2004-02-09 20:06:41.000000000 +0100
@@ -1,6 +1,6 @@
 #! perl -w
 
-use Parrot::Test tests => 2;
+use Parrot::Test tests => 3;
 use Test::More;
 
 output_is(<<'CODE', <<'OUT', 'traverse key chain');
@@ -64,3 +64,58 @@
 ok 1
 123
 OUT
+
+my $qr = "0\n0.00*\n\n\n" x 3;
+$qr = qr|$qr|;
+
+output_like(<<'CODE', $qr, 'mere PMCs used as keys');
+   new P0, .Array
+   set P0, 1
+
+   new P1, .PerlInt
+   set P1, 0
+   set I2, P0[P1]
+   print I2
+   print "\n"
+   set N2, P0[P1]
+   print N2
+   print "\n"
+   set S2, P0[P1]
+   print S2
+   print "\n"
+   set P2,  P0[P1]
+   print P2
+   print "\n"
+
+   new P1, .PerlString
+   set P1, "0"
+   set I2, P0[P1]
+   print I2
+   print "\n"
+   set N2, P0[P1]
+   print N2
+   print "\n"
+   set S2,  P0[P1]
+   print S2
+   print "\n"
+   set P2, P0[P1]
+   print P2
+   print "\n"
+
+   new P1, .PerlNum
+   set P1, 0.0
+   set I2, P0[P1]
+   print I2
+   print "\n"
+   set N2, P0[P1]
+   print N2
+   print "\n"
+   set S2, P0[P1]
+   print S2
+   print "\n"
+   set P2, P0[P1]
+   print P2
+   print "\n"
+   end
+CODE
+

Reply via email to