Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Hash iteration should return pairs

For consistency with Parrot itself, and Rakudo.  I had a horrible misconception
about this for a while.
  • Loading branch information...
commit 801e5196900fbddb34ab0bbc7d6c5dba32950827 1 parent 9dc204c
@sorear sorear authored
View
3  build/Makefile.in
@@ -75,7 +75,8 @@ PMC_SOURCES = \
src/pmc/p5scalar.pmc \
src/pmc/p5hashiter.pmc \
src/pmc/p5namespace.pmc \
- src/pmc/p5invocation.pmc
+ src/pmc/p5invocation.pmc \
+ src/pmc/p5hashiterresult.pmc
PMC_C = $(PMC_SOURCES:.pmc=.c)
PMC_DUMP = $(PMC_SOURCES:.pmc=.dump)
View
29 nt/iterator.t
@@ -1,6 +1,6 @@
# vim: ft=perl6
-plan(9);
+plan(15);
my $p5code := '{ foo => 2, bar => 7 }';
@@ -9,19 +9,36 @@ my $p5obj := pir::compreg__ps("perl5").make_interp($p5code)();
my %expected;
my $got;
+my $iter;
+
+$iter := pir::iter__pp($p5obj);
+$got := pir::shift__pp($iter);
+if $got.key eq 'foo' {
+ $got := pir::shift__pp($iter);
+}
+
+ok((~$got.key) eq 'bar', "iterator results have keys accessible on .key");
+ok((~$got) eq 'bar', "iterator results stringify to keys");
+ok((+$got.value) == 7, "iterator values are accessible on .value");
+ok((~pir::deref__PP($got)) eq 'bar', "iterator keys are on get_pmc");
+
+pir::shift__pp(pir::iter__pp($p5obj));
+
+ok((~$got.key) eq 'bar', "pair keys remain accessible after a new iteration");
+ok((+$got.value) == 7, "pair values remain accessible after a new iteration");
%expected<foo> := 1;
%expected<bar> := 1;
-my $iter := pir::iter__pp($p5obj);
+$iter := pir::iter__pp($p5obj);
ok(?$iter, "iterator reports more elements [0/2]");
-$got := pir::shift__pp($iter);
+$got := ~pir::shift__pp($iter);
ok(%expected{$got}, "got foo or bar [0/2]");
%expected{$got} := 0;
ok(?$iter, "iterator reports more elements [1/2]");
-$got := pir::shift__pp($iter);
+$got := ~pir::shift__pp($iter);
ok(%expected{$got}, "got the other [1/2]");
%expected{$got} := 0;
@@ -39,11 +56,11 @@ ok(!?$iter, "iterator reports no more elements [2/2]");
$iter := pir::iter__pp($p5obj);
-$got := pir::shift__pp($iter);
+$got := ~pir::shift__pp($iter);
ok(%expected{$got}, "got foo or bar without priming [0/2]");
%expected{$got} := 0;
-$got := pir::shift__pp($iter);
+$got := ~pir::shift__pp($iter);
ok(%expected{$got}, "got the other without priming [1/2]");
%expected{$got} := 0;
View
1  src/pmc/blizkost.h
@@ -61,6 +61,7 @@ does the necessary cruft to import both in the same file.
#include "pmc_p5sv.h"
#include "pmc_p5scalar.h"
#include "pmc_p5hashiter.h"
+#include "pmc_p5hashiterresult.h"
extern HE blizkost_EMPTY;
View
17 src/pmc/p5hashiter.pmc
@@ -77,8 +77,8 @@ Mark GC-ables.
VTABLE PMC *shift_pmc() {
HE *current_he = force_current_he(INTERP, SELF);
- SV *keysv;
- PMC *p5i, *hash;
+ SV *hashsv;
+ PMC *p5i, *hash, *tmppmc, *retpmc;
PerlInterpreter *my_perl;
if (current_he == NULL) {
@@ -90,10 +90,19 @@ Mark GC-ables.
GET_ATTR_backing_hash(INTERP, SELF, hash);
GETATTR_P5SV_p5i(INTERP, hash, p5i);
+ GETATTR_P5SV_sv(INTERP, hash, hashsv);
GETATTR_P5Interpreter_my_perl(INTERP, p5i, my_perl);
- keysv = hv_iterkeysv(current_he);
+ retpmc = Parrot_pmc_new_noinit(interp, pmc_type(interp,
+ string_from_literal(interp, "P5HashIterResult")));
+ PObj_custom_mark_SET(retpmc);
- return blizkost_wrap_sv(INTERP, p5i, keysv);
+ SETATTR_P5HashIterResult_hekey(INTERP, retpmc,
+ blizkost_wrap_sv(INTERP, p5i, hv_iterkeysv(current_he)));
+ SETATTR_P5HashIterResult_hevalue(INTERP, retpmc,
+ blizkost_wrap_sv(INTERP, p5i,
+ hv_iterval((HV*)hashsv, current_he)));
+
+ return retpmc;
}
}
View
58 src/pmc/p5hashiterresult.pmc
@@ -0,0 +1,58 @@
+/*
+Copyright (C) 2009, Jonathan Worthington and friends
+
+This file is distributed under the same terms as Parrot itself; see the
+file LICENSE in the source root for details.
+
+=head1 NAME
+
+src/pmc/p5hashiterresult.pmc - Perl 5 hash entry
+
+=head1 DESCRIPTION
+
+This module provides a pair for p5hashiter to return.
+
+=cut
+
+*/
+
+#include "blizkost.h"
+
+pmclass P5HashIterResult no_ro group blizkost_group dynpmc auto_attrs {
+ ATTR PMC *hekey;
+ ATTR PMC *hevalue;
+
+ VTABLE void init() {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "Attempt to directly instantiate a P5HashIterResult");
+ }
+
+ VTABLE void mark() {
+ PMC *key;
+ PMC *value;
+ GET_ATTR_hekey(interp, SELF, key);
+ GET_ATTR_hevalue(interp, SELF, value);
+ if (key)
+ Parrot_gc_mark_PObj_alive(interp, (PObj*)key);
+ if (value)
+ Parrot_gc_mark_PObj_alive(interp, (PObj*)value);
+ }
+
+ VTABLE PMC *get_pmc() {
+ return PARROT_P5HASHITERRESULT(SELF)->hekey;
+ }
+
+ METHOD key() {
+ PMC *ret = PARROT_P5HASHITERRESULT(SELF)->hekey;
+ RETURN(PMC *ret);
+ }
+
+ METHOD value() {
+ PMC *ret = PARROT_P5HASHITERRESULT(SELF)->hevalue;
+ RETURN(PMC *ret);
+ }
+
+ VTABLE STRING* get_string() {
+ return VTABLE_get_string(INTERP, PARROT_P5HASHITERRESULT(SELF)->hekey);
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.