cvsuser 04/06/25 09:35:52
Modified: classes perlhash.pmc
t/pmc iter.t
Log:
fromkeys again
Revision Changes Path
1.75 +75 -6 parrot/classes/perlhash.pmc
Index: perlhash.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/perlhash.pmc,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -w -r1.74 -r1.75
--- perlhash.pmc 25 Jun 2004 10:19:52 -0000 1.74
+++ perlhash.pmc 25 Jun 2004 16:35:48 -0000 1.75
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: perlhash.pmc,v 1.74 2004/06/25 10:19:52 leo Exp $
+$Id: perlhash.pmc,v 1.75 2004/06/25 16:35:48 leo Exp $
=head1 NAME
@@ -29,6 +29,20 @@
#include "parrot/parrot.h"
+static size_t
+key_hash_int(Interp *interp, Hash *hash, void *value)
+{
+ UNUSED(interp);
+ UNUSED(hash);
+ return (size_t) value;
+}
+
+static int
+int_compare(Parrot_Interp interp, void *a, void *b)
+{
+ UNUSED(interp);
+ return a != b;
+}
static void
fromkeys(Interp *interpreter, PMC *self, PMC *keys, PMC *value)
{
@@ -58,6 +72,38 @@
VTABLE_isa(interpreter, keys,
const_string(interpreter, "Iterator"))) {
iter = keys;
+ if (PMC_struct_val(iter)) {
+ PMC *xr = PMC_struct_val(iter);
+ /* check, if we got an xrange iterator */
+ if (PObj_is_PMC_TEST(xr) &&
+ xr->vtable->base_type == enum_class_Slice &&
+ PMC_data(xr)) {
+ PMC *range = PMC_data(xr);
+ if (((PObj_get_FLAGS(xr) &
+ (KEY_inf_slice_FLAG|KEY_start_slice_FLAG)) ==
+ KEY_start_slice_FLAG &&
+ ((PObj_get_FLAGS(range) &
+ (KEY_inf_slice_FLAG|KEY_end_slice_FLAG)) ==
+ KEY_end_slice_FLAG))) {
+ INTVAL start, end, step = 1;
+ Hash* hash;
+ new_hash_x(interpreter, &hash, enum_type_ptr,
+ 0, Hash_key_type_int,
+ int_compare, key_hash_int,
+ (hash_mark_key_fn) NULL);
+ PMC_struct_val(self) = hash;
+ start = key_integer(interpreter, xr);
+ end = key_integer(interpreter, range);
+ /* TODO step
+ * TODO reversed range, negative step
+ */
+ for (i = start; i < end; i+= step) {
+ hash_put(interpreter, hash, (void *)i, value);
+ }
+ goto done;
+ }
+ }
+ }
}
else
iter = pmc_new_init(interpreter, enum_class_Iterator, keys);
@@ -66,6 +112,7 @@
STRING *s = VTABLE_shift_string(interpreter, iter);
VTABLE_set_pmc_keyed_str(interpreter, self, s, value);
}
+done:
if (dod_disabled) {
Parrot_unblock_DOD(interpreter);
Parrot_unblock_GC(interpreter);
@@ -260,10 +307,27 @@
INTVAL get_integer_keyed (PMC* key) {
PMC* valpmc;
- STRING* keystr = make_hash_key(INTERP, key);
- HashBucket *b = hash_get_bucket(INTERP, (Hash*) PMC_struct_val(SELF),
- keystr);
+ STRING* keystr;
+ Hash *hash = PMC_struct_val(SELF);
+ HashBucket *b;
PMC* nextkey;
+
+ switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
+ case KEY_integer_FLAG:
+ /* called from iterator with an integer idx in key
+ * check if we really have Hash_key_type_int
+ */
+ if (hash->key_type == Hash_key_type_int) {
+ return (INTVAL)hash_get_idx(INTERP, hash, key);
+ }
+ else {
+ STRING *s = hash_get_idx(INTERP, hash, key);
+ return string_to_int(interpreter, s);
+ }
+ default:
+ keystr = make_hash_key(INTERP, key);
+ }
+ b = hash_get_bucket(INTERP, hash, keystr);
if (b == NULL) {
/* XXX Warning: use of uninitialized value */
return VTABLE_get_integer(INTERP, undef);
@@ -412,16 +476,21 @@
PMC* valpmc;
STRING* keystr;
HashBucket *b;
+ Hash *hash = PMC_struct_val(SELF);
PMC* nextkey;
switch (PObj_get_FLAGS(key) & KEY_type_FLAGS) {
case KEY_integer_FLAG:
/* called from iterator with an integer idx in key */
- return hash_get_idx(INTERP, (Hash*) PMC_struct_val(SELF), key);
+ if (hash->key_type == Hash_key_type_int) {
+ INTVAL i = (INTVAL)hash_get_idx(INTERP, hash, key);
+ return string_from_int(interpreter, i);
+ }
+ return hash_get_idx(INTERP, hash, key);
default:
keystr = make_hash_key(INTERP, key);
}
- b = hash_get_bucket(INTERP, (Hash*) PMC_struct_val(SELF), keystr);
+ b = hash_get_bucket(INTERP, hash, keystr);
if (b == NULL) {
/* XXX Warning: use of uninitialized value */
return VTABLE_get_string(INTERP, undef);
1.21 +33 -2 parrot/t/pmc/iter.t
Index: iter.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/iter.t,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -w -r1.20 -r1.21
--- iter.t 25 Jun 2004 10:20:08 -0000 1.20
+++ iter.t 25 Jun 2004 16:35:52 -0000 1.21
@@ -1,6 +1,6 @@
#! perl -w
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: iter.t,v 1.20 2004/06/25 10:20:08 leo Exp $
+# $Id: iter.t,v 1.21 2004/06/25 16:35:52 leo Exp $
=head1 NAME
@@ -16,7 +16,7 @@
=cut
-use Parrot::Test tests => 37;
+use Parrot::Test tests => 38;
use Test::More qw(skip);
output_is(<<'CODE', <<'OUTPUT', "new iter");
@@ -1223,3 +1223,34 @@
CODE
/10 [0123456789]{10}ok/
OUTPUT
+
+output_like(<<'CODE', <<'OUTPUT', "hash fromkeys - xrange");
+##PIR##
+.sub main @MAIN
+ .include "iterator.pasm"
+ .local pmc hash
+ .local pmc value
+ .local pmc xr
+ xr = new Slice
+ .local pmc sl
+ sl = slice xr[0 .. 10]
+ hash = new PerlHash
+ null value
+ hash."fromkeys"(sl, value)
+ $I0 = hash
+ print $I0
+ print " "
+ .local pmc iter
+ iter = new .Iterator, hash
+ iter = .ITERATE_FROM_START
+iter_loop:
+ unless iter, iter_end # while (entries) ...
+ $I0 = shift iter
+ print $I0
+ goto iter_loop
+iter_end:
+ print "ok\n"
+.end
+CODE
+/10 [0123456789]{10}ok/
+OUTPUT