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
+