[svn:parrot] r43586 - in trunk: . include/parrot src src/pmc t/native_pbc t/pmc
bacek at svn.parrot.org
bacek at svn.parrot.org
Mon Jan 25 13:50:25 UTC 2010
Author: bacek
Date: Mon Jan 25 13:50:23 2010
New Revision: 43586
URL: https://trac.parrot.org/parrot/changeset/43586
Log:
Merge branch orderedhash_revamp into trunk
Modified:
trunk/MANIFEST.SKIP
trunk/include/parrot/hash.h
trunk/src/pmc/orderedhash.pmc
trunk/src/pmc/orderedhashiterator.pmc
trunk/src/pmc/unmanagedstruct.pmc
trunk/src/pmc_freeze.c
trunk/t/native_pbc/annotations.pbc
trunk/t/native_pbc/integer_1.pbc
trunk/t/native_pbc/number_1.pbc
trunk/t/native_pbc/string_1.pbc
trunk/t/pmc/orderedhash.t
Modified: trunk/MANIFEST.SKIP
==============================================================================
--- trunk/MANIFEST.SKIP Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/MANIFEST.SKIP Mon Jan 25 13:50:23 2010 (r43586)
@@ -1,6 +1,6 @@
# ex: set ro:
# $Id$
-# generated by tools/dev/mk_manifest_and_skip.pl Wed Dec 16 15:31:13 2009 UT
+# generated by tools/dev/mk_manifest_and_skip.pl Sat Jan 23 10:27:18 2010 UT
#
# This file should contain a transcript of the svn:ignore properties
# of the directories in the Parrot subversion repository. (Needed for
@@ -83,12 +83,6 @@
^myconfig/
^parrot$
^parrot/
-^parrot-nqp$
-^parrot-nqp/
-^parrot-nqp\.c$
-^parrot-nqp\.c/
-^parrot-nqp\.pbc$
-^parrot-nqp\.pbc/
^parrot\.ilk$
^parrot\.ilk/
^parrot\.iss$
@@ -149,16 +143,6 @@
^vc70\.pdb/
^vtable\.dump$
^vtable\.dump/
-# generated from svn:ignore of 'compilers/data_json/'
-^compilers/data_json/Makefile$
-^compilers/data_json/Makefile/
-^compilers/data_json/data_json\.pbc$
-^compilers/data_json/data_json\.pbc/
-# generated from svn:ignore of 'compilers/data_json/data_json/'
-^compilers/data_json/data_json/.*\.pbc$
-^compilers/data_json/data_json/.*\.pbc/
-^compilers/data_json/data_json/.*\.pir$
-^compilers/data_json/data_json/.*\.pir/
# generated from svn:ignore of 'compilers/imcc/'
^compilers/imcc/.*\.flag$
^compilers/imcc/.*\.flag/
@@ -279,8 +263,6 @@
^docs/.*\.tmp/
^docs/Makefile$
^docs/Makefile/
-^docs/doc-prep$
-^docs/doc-prep/
^docs/html$
^docs/html/
^docs/packfile-c\.pod$
@@ -315,8 +297,8 @@
^examples/languages/abc/.*\.obj/
^examples/languages/abc/.*\.pbc$
^examples/languages/abc/.*\.pbc/
-^examples/languages/abc/MANIFEST$
-^examples/languages/abc/MANIFEST/
+^examples/languages/abc/Makefile$
+^examples/languages/abc/Makefile/
^examples/languages/abc/abc$
^examples/languages/abc/abc/
^examples/languages/abc/installable_abc$
@@ -348,10 +330,12 @@
^examples/languages/squaak/.*\.obj/
^examples/languages/squaak/.*\.pbc$
^examples/languages/squaak/.*\.pbc/
-^examples/languages/squaak/MANIFEST$
-^examples/languages/squaak/MANIFEST/
+^examples/languages/squaak/Makefile$
+^examples/languages/squaak/Makefile/
^examples/languages/squaak/installable_squaak$
^examples/languages/squaak/installable_squaak/
+^examples/languages/squaak/man$
+^examples/languages/squaak/man/
^examples/languages/squaak/squaak$
^examples/languages/squaak/squaak/
# generated from svn:ignore of 'examples/languages/squaak/src/'
@@ -385,8 +369,8 @@
^examples/pir/befunge/.*\.obj/
^examples/pir/befunge/.*\.pbc$
^examples/pir/befunge/.*\.pbc/
-^examples/pir/befunge/MANIFEST$
-^examples/pir/befunge/MANIFEST/
+^examples/pir/befunge/Makefile$
+^examples/pir/befunge/Makefile/
^examples/pir/befunge/befunge$
^examples/pir/befunge/befunge/
^examples/pir/befunge/installable_befunge$
@@ -461,11 +445,6 @@
# generated from svn:ignore of 'ext/Parrot-Embed/t/'
^ext/Parrot-Embed/t/.*\.pbc$
^ext/Parrot-Embed/t/.*\.pbc/
-# generated from svn:ignore of 'ext/nqp-rx/'
-^ext/nqp-rx/.*\.pbc$
-^ext/nqp-rx/.*\.pbc/
-^ext/nqp-rx/Makefile$
-^ext/nqp-rx/Makefile/
# generated from svn:ignore of 'include/parrot/'
^include/parrot/.*\.tmp$
^include/parrot/.*\.tmp/
@@ -498,9 +477,6 @@
^include/parrot/oplib/.*_ops_switch\.h/
^include/parrot/oplib/ops\.h$
^include/parrot/oplib/ops\.h/
-# generated from svn:ignore of 'include/pmc/'
-^include/pmc/.*\.h$
-^include/pmc/.*\.h/
# generated from svn:ignore of 'lib/'
^lib/DumbLink\.pm$
^lib/DumbLink\.pm/
@@ -578,9 +554,6 @@
# generated from svn:ignore of 'runtime/parrot/library/Config/'
^runtime/parrot/library/Config/.*\.pbc$
^runtime/parrot/library/Config/.*\.pbc/
-# generated from svn:ignore of 'runtime/parrot/library/Configure/'
-^runtime/parrot/library/Configure/.*\.pbc$
-^runtime/parrot/library/Configure/.*\.pbc/
# generated from svn:ignore of 'runtime/parrot/library/Data/'
^runtime/parrot/library/Data/.*\.pbc$
^runtime/parrot/library/Data/.*\.pbc/
@@ -694,8 +667,6 @@
^src/atomic/.*\.o$
^src/atomic/.*\.o/
# generated from svn:ignore of 'src/call/'
-^src/call/.*\.o$
-^src/call/.*\.o/
^src/call/.*\.obj$
^src/call/.*\.obj/
^src/call/.*\.str$
@@ -814,8 +785,6 @@
^src/gc/Makefile$
^src/gc/Makefile/
# generated from svn:ignore of 'src/interp/'
-^src/interp/.*\.o$
-^src/interp/.*\.o/
^src/interp/.*\.str$
^src/interp/.*\.str/
# generated from svn:ignore of 'src/io/'
@@ -854,13 +823,6 @@
^src/pmc/.*\.tmp/
^src/pmc/Makefile$
^src/pmc/Makefile/
-# generated from svn:ignore of 'src/runcore/'
-^src/runcore/.*\.o$
-^src/runcore/.*\.o/
-^src/runcore/.*\.obj$
-^src/runcore/.*\.obj/
-^src/runcore/.*\.str$
-^src/runcore/.*\.str/
# generated from svn:ignore of 'src/string/'
^src/string/.*\.o$
^src/string/.*\.o/
Modified: trunk/include/parrot/hash.h
==============================================================================
--- trunk/include/parrot/hash.h Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/include/parrot/hash.h Mon Jan 25 13:50:23 2010 (r43586)
@@ -80,6 +80,16 @@
typedef void (*value_free)(void *);
+/* To avoid creating OrderedHashItem PMC we reuse FixedPMCArray PMC */
+/* So, there is indexes to avoid using of "magick constants" */
+enum ORDERED_HASH_ITEM_PART {
+ ORDERED_HASH_ITEM_KEY = 0,
+ ORDERED_HASH_ITEM_VALUE = 1,
+ ORDERED_HASH_ITEM_PREV = 2,
+ ORDERED_HASH_ITEM_NEXT = 3,
+ ORDERED_HASH_ITEM_MAX = 4,
+};
+
/* HEADERIZER BEGIN: src/hash.c */
/* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */
Modified: trunk/src/pmc/orderedhash.pmc
==============================================================================
--- trunk/src/pmc/orderedhash.pmc Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/src/pmc/orderedhash.pmc Mon Jan 25 13:50:23 2010 (r43586)
@@ -8,28 +8,66 @@
=head1 DESCRIPTION
-C<OrderedHash> extends C<Hash> to provide the interfaces of C<array> and
-C<hash>. To achieve ordering, hash there are a few restrictions:
-C<delete_keyed> never removes items; they are just nulled.
-
-Please note that if values are set via integer idx, these indices have to be in
-strict order. Using C<push_xx> simplifies this task. This creates a key
-"\1idx" for C<idx> and is therefore not fully transparent.
+C<OrderedHash> provide the interfaces of C<array> and
+C<hash>.
-There are two iterator interfaces:
+Some limitations:
=over 4
-=item * retrieve values (in creation order)
+=item *
-Please note that after a C<delete_keyed> operation, iterating over
-values doesn't work any more. You'll get an error 'No such key'.
+Keys are always STRING*.
-=item * retrieve keys (in creation order)
+=item *
+
+Values are always PMC*.
+
+=back
+
+To archive ordering for each item we store:
+
+=over 4
+
+=item * C<key>
+
+Original key
+
+=item * C<value>
+
+Original value
+
+=item * C<next>
+
+Pointer to next C<item>
+
+=item * C<prev>
+
+Pointer to previous C<item>
+
+=back
+
+OrderedHash stores next things:
+
+=over 4
+
+=item * C<hash>
+
+Lookup hash for values.
+
+=item * C<first>
+
+Pointer to first inserted value.
+
+=item * C<last>
+
+Pointer to last inserter value.
=back
-See F<t/pmc/orderedhash.t>.
+See F<t/pmc/orderedhash.t> for test cases.
+
+Overall design heavily inspired by C<Tie::StoredOrderHash>.
=head2 Methods
@@ -39,39 +77,127 @@
*/
-pmclass OrderedHash extends Hash provides array provides hash {
+/* Create new stored item. FixedPMCArray of (key, value, prev, next). */
+static PMC*
+create_item(PARROT_INTERP, ARGIN(PMC *key), ARGIN(PMC *value)) {
+ PMC *ret = pmc_new(interp, enum_class_FixedPMCArray);
+ VTABLE_set_integer_native(interp, ret, ORDERED_HASH_ITEM_MAX);
+
+ VTABLE_set_pmc_keyed_int(interp, ret, ORDERED_HASH_ITEM_KEY, key);
+ VTABLE_set_pmc_keyed_int(interp, ret, ORDERED_HASH_ITEM_VALUE, value);
+ return ret;
+};
+
+/* Get list_item by index */
+static PMC*
+get_list_item(PARROT_INTERP, ARGIN(PMC *self), INTVAL idx) {
+ Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(self);
+ INTVAL n = VTABLE_elements(interp, attrs->hash);
+ INTVAL pos;
+ PMC *list_entry = attrs->first;
+
+ if (idx < -n)
+ idx = -idx - n - 1;
+ else if (idx < 0)
+ idx += n;
+
+ /* Iterate over linked list to get list_item */
+ for (pos = 0; pos < idx; ++pos) {
+ list_entry = VTABLE_get_pmc_keyed_int(interp, list_entry, ORDERED_HASH_ITEM_NEXT);
+ }
+ return list_entry;
+}
+
+/* Find first/last in cloned/thawed OrderedHash */
+/* Parameter C<pmc_hash> is Hash, not OrderedHash */
+static void
+find_bounds(PARROT_INTERP, PMC *pmc_hash, PMC **first, PMC **last) {
+ PMC *iter = VTABLE_get_iter(interp, pmc_hash);
+ while (VTABLE_get_bool(interp, iter)) {
+ PMC *item = VTABLE_shift_pmc(interp, iter);
+ PMC *entry = VTABLE_get_pmc_keyed(interp, pmc_hash, item);
+ /* First entry doesn't have prev */
+ PMC *tmp = VTABLE_get_pmc_keyed_int(interp, entry, ORDERED_HASH_ITEM_PREV);
+ if (PMC_IS_NULL(tmp))
+ *first = entry;
+ /* Last entry doesn't have next */
+ tmp = VTABLE_get_pmc_keyed_int(interp, entry, ORDERED_HASH_ITEM_NEXT);
+ if (PMC_IS_NULL(tmp))
+ *last = entry;
+ }
+}
+
+/* Helpers for boxing values */
+static PMC*
+box_string(PARROT_INTERP, STRING *str) {
+ PMC * const ret = pmc_new(interp, Parrot_get_ctx_HLL_type(interp,
+ enum_class_String));
+ VTABLE_set_string_native(interp, ret, str);
+ return ret;
+}
+
+static PMC*
+box_integer(PARROT_INTERP, INTVAL val) {
+ PMC * const ret = pmc_new(interp, Parrot_get_ctx_HLL_type(interp,
+ enum_class_Integer));
+ VTABLE_set_integer_native(interp, ret, val);
+ return ret;
+}
+
+static PMC*
+box_number(PARROT_INTERP, FLOATVAL val) {
+ PMC * const ret = pmc_new(interp, Parrot_get_ctx_HLL_type(interp,
+ enum_class_Float));
+ VTABLE_set_number_native(interp, ret, val);
+ return ret;
+}
+
+
+pmclass OrderedHash need_ext provides array provides hash {
+ ATTR PMC *hash; /* key to item tuple */
+ ATTR PMC *first; /* Pointer to first inserted value */
+ ATTR PMC *last; /* Pointer to last inserted value */
/*
-=item C<void mark()>
+=item C<void init()>
-Marks the OrderedHash as live.
+Create new instance of OrderedHash.
=cut
*/
- VTABLE void mark() {
- Hash * const h = (Hash *)SELF.get_pointer();
- INTVAL i;
+ VTABLE void init() {
+ Parrot_OrderedHash_attributes * const attrs =
+ mem_allocate_zeroed_typed(Parrot_OrderedHash_attributes);
- if (!h)
- return;
+ PMC_data(SELF) = attrs;
+ attrs->hash = pmc_new(INTERP, enum_class_Hash);
+ attrs->first = PMCNULL;
+ attrs->last = PMCNULL;
- for (i = h->mask; i >= 0; --i) {
- HashBucket *b = h->bi[i];
+ PObj_custom_mark_destroy_SETALL(SELF);
+ }
- while (b) {
+/*
- if (b->key) {
- Parrot_gc_mark_PObj_alive(interp, (PObj *)b->key);
- if (b->value)
- Parrot_gc_mark_PObj_alive(interp, (PObj *)b->value);
- }
+=item C<void mark()>
- b = b->next;
- }
- }
+Marks the OrderedHash as live.
+
+=cut
+
+*/
+
+ VTABLE void mark() {
+ Parrot_OrderedHash_attributes * const attrs =
+ PARROT_ORDEREDHASH(SELF);
+
+ if (attrs->hash)
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *)attrs->hash);
+
+ /* Don't mark C<first> and C<last>. They are in lookup hash anyway */
}
/*
@@ -90,195 +216,247 @@
/*
-=item C<PMC *get_pmc_keyed(PMC *key)>
+=item C<INTVAL elements()>
-=item C<PMC *get_pmc_keyed_int(INTVAL key)>
+=item C<INTVAL get_integer()>
-=item C<PMC *get_pmc_keyed_str(STRING *key)>
+=item C<FLOATVAL get_number()>
+
+Returns the size of the hash.
=cut
*/
- VTABLE PMC *get_pmc_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
+ VTABLE INTVAL get_integer() {
+ return STATICSELF.elements();
+ }
- if (idx < 0)
- idx += n;
+ VTABLE FLOATVAL get_number() {
+ return SELF.get_integer();
+ }
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: index out of bounds!");
+ VTABLE INTVAL elements() {
+ return VTABLE_elements(INTERP, PARROT_ORDEREDHASH(SELF)->hash);
+ }
- b = h->bs + idx;
+/*
- if (b->key)
- return (PMC *)b->value;
+=item C<set_pmc_keyed(PMC *key, PMC *value)>
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
- }
+Main set function.
- VTABLE PMC *get_pmc_keyed(PMC *key) {
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
+=cut
- if (!next)
- return item;
+*/
+ VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
+ Parrot_OrderedHash_attributes *attrs =
+ PARROT_ORDEREDHASH(SELF);
- return VTABLE_get_pmc_keyed(INTERP, item, next);
+ /* Check for old entry */
+ PMC *list_entry = VTABLE_get_pmc_keyed(INTERP, attrs->hash, key);
+ if (!PMC_IS_NULL(list_entry)) {
+ /* We have old entry. Just update value */
+ PMC *nextkey = key_next(INTERP, key);
+ if (nextkey) {
+ PMC *old_value = VTABLE_get_pmc_keyed_int(INTERP, list_entry,
+ ORDERED_HASH_ITEM_VALUE);
+ VTABLE_set_pmc_keyed(INTERP, value, nextkey, value);
+ }
+ else
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, value);
+ return;
}
- return INTERP->vtables[enum_class_Hash]->get_pmc_keyed(INTERP, SELF, key);
- }
+ /* Create new entry */
+ list_entry = pmc_new(INTERP, enum_class_FixedPMCArray);
+ VTABLE_set_integer_native(INTERP, list_entry, ORDERED_HASH_ITEM_MAX);
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, value);
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_KEY, key);
+
+ /* .. and link it */
+ if (!PMC_IS_NULL(attrs->last)) {
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_PREV, attrs->last);
+ VTABLE_set_pmc_keyed_int(INTERP, attrs->last, ORDERED_HASH_ITEM_NEXT, list_entry);
+ }
+ attrs->last = list_entry;
+ if (PMC_IS_NULL(attrs->first))
+ attrs->first = list_entry;
+ /* .. and store it */
+ VTABLE_set_pmc_keyed(INTERP, attrs->hash, key, list_entry);
+ }
/*
-=item C<STRING *get_string_keyed(PMC *key)>
+=item C<void set_integer_keyed(INTVAL key, INTVAL value)>
-=item C<STRING *get_string_keyed_int(INTVAL key)>
+=item C<void set_number_keyed(INTVAL key, FLOATVAL value)>
-=item C<STRING *get_string_keyed_str(STRING *key)>
+=item C<void set_string_keyed(INTVAL key, STRING *value)>
+
+Sets the PMC value of the element at index C<key> to C<val>.
=cut
*/
- VTABLE STRING *get_string_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
+ VTABLE void set_integer_keyed(PMC *key, INTVAL value) {
+ PMC * const v = box_integer(INTERP, value);
+ SELF.set_pmc_keyed(key, v);
+ }
- HashBucket *b;
+ VTABLE void set_number_keyed(PMC *key, FLOATVAL value) {
+ PMC * const v = box_number(INTERP, value);
+ SELF.set_pmc_keyed(key, v);
+ }
- if (idx < 0)
- idx += n;
+ VTABLE void set_string_keyed(PMC *key, STRING *value) {
+ PMC * const v = box_string(INTERP, value);
+ SELF.set_pmc_keyed(key, v);
+ }
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: index out of bounds!");
+/*
- b = h->bs + idx;
+=item C<void set_pmc_keyed_str(STRING *key, PMC *val)>
- if (b->key)
- return VTABLE_get_string(INTERP, (PMC *)b->value);
+=item C<void set_integer_keyed_str(STRING *key, INTVAL value)>
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
- }
+=item C<void set_number_keyed_str(STRING *key, FLOATVAL value)>
- VTABLE STRING *get_string_keyed(PMC *key) {
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
+=item C<void set_string_keyed_str(STRING *key, STRING *value)>
- if (!next)
- return VTABLE_get_string(INTERP, item);
+Sets the PMC value of the element at index C<key> to C<val>.
- return VTABLE_get_string_keyed(INTERP, item, next);
- }
+=cut
+
+*/
- return INTERP->vtables[enum_class_Hash]->get_string_keyed(INTERP, SELF, key);
+ VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
+ PMC *pkey = box_string(INTERP, key);
+ VTABLE_set_pmc_keyed(INTERP, SELF, pkey, value);
}
-/*
-=item C<INTVAL get_integer_keyed(PMC *key)>
+ VTABLE void set_string_keyed_str(STRING *key, STRING *value) {
+ PMC * const v = box_string(INTERP, value);
+ STATICSELF.set_pmc_keyed_str(key, v);
+ }
-=item C<INTVAL get_integer_keyed_str(STRING *key)>
+ VTABLE void set_integer_keyed_str(STRING *key, INTVAL value) {
+ PMC * const v = box_integer(INTERP, value);
+ STATICSELF.set_pmc_keyed_str(key, v);
+ }
-=item C<INTVAL get_integer_keyed_int(INTVAL key)>
+ VTABLE void set_number_keyed_str(STRING *key, FLOATVAL value) {
+ PMC * const v = box_number(INTERP, value);
+ STATICSELF.set_pmc_keyed_str(key, v);
+ }
-Returns the integer value associated with C<key>.
+/*
+
+=item C<PMC *get_pmc_keyed(PMC *key)>
+
+=item C<PMC *get_pmc_keyed_int(INTVAL key)>
+
+=item C<PMC *get_pmc_keyed_str(STRING *key)>
=cut
*/
- VTABLE INTVAL get_integer_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
+ VTABLE PMC *get_pmc_keyed_int(INTVAL idx) {
+ PMC *list_entry = get_list_item(INTERP, SELF, idx);
- if (idx < 0)
- idx += n;
+ if (PMC_IS_NULL(list_entry))
+ return PMCNULL;
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "OrderedHash: index out of bounds!");
+ return VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE);
+ }
- b = h->bs + idx;
+ VTABLE PMC *get_pmc_keyed(PMC *key) {
+ PMC * item;
+ /* Access by integer index */
+ if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
+ return SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
+ }
- if (b->key)
- return VTABLE_get_integer(INTERP, (PMC *)b->value);
+ item = VTABLE_get_pmc_keyed(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
+ if (PMC_IS_NULL(item))
+ return PMCNULL;
+ return VTABLE_get_pmc_keyed_int(INTERP, item, ORDERED_HASH_ITEM_VALUE);
+ }
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
+ VTABLE PMC *get_pmc_keyed_str(STRING *key) {
+ PMC *pkey = pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_String));
+ VTABLE_set_string_native(INTERP, pkey, key);
+ return STATICSELF.get_pmc_keyed(pkey);
}
+/*
- VTABLE INTVAL get_integer_keyed(PMC *key) {
+=item C<STRING *get_string_keyed(PMC *key)>
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
+=item C<STRING *get_string_keyed_int(INTVAL key)>
- if (!next)
- return VTABLE_get_integer(INTERP, item);
+=item C<STRING *get_string_keyed_str(STRING *key)>
- return VTABLE_get_integer_keyed(INTERP, item, next);
- }
+=cut
+
+*/
- return INTERP->vtables[enum_class_Hash]->get_integer_keyed(INTERP, SELF, key);
+ VTABLE STRING *get_string_keyed_int(INTVAL idx) {
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_string(INTERP, item);
}
+ VTABLE STRING *get_string_keyed(PMC *key) {
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_string(INTERP, item);
+ }
/*
-=item C<FLOATVAL get_number_keyed(PMC *key)>
+=item C<INTVAL get_integer_keyed(PMC *key)>
-=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
+=item C<INTVAL get_integer_keyed_str(STRING *key)>
-=item C<FLOATVAL get_number_keyed_str(STRING *key)>
+=item C<INTVAL get_integer_keyed_int(INTVAL key)>
-Returns the floating-point value for the element at C<key>.
+Returns the integer value associated with C<key>.
=cut
*/
- VTABLE FLOATVAL get_number_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
+ VTABLE INTVAL get_integer_keyed_int(INTVAL idx) {
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_integer(INTERP, item);
+ }
- if (idx < 0)
- idx += n;
+ VTABLE INTVAL get_integer_keyed(PMC *key) {
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_integer(INTERP, item);
+ }
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "OrderedHash: index out of bounds!");
+/*
- b = h->bs + idx;
+=item C<FLOATVAL get_number_keyed(PMC *key)>
- if (b->key)
- return VTABLE_get_number(INTERP, (PMC *)b->value);
+=item C<FLOATVAL get_number_keyed_int(INTVAL key)>
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
- }
+=item C<FLOATVAL get_number_keyed_str(STRING *key)>
- VTABLE FLOATVAL get_number_keyed(PMC *key) {
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
+Returns the floating-point value for the element at C<key>.
- if (!next)
- return VTABLE_get_number(INTERP, item);
+=cut
- return VTABLE_get_number_keyed(INTERP, item, next);
- }
+*/
- return SUPER(key);
+ VTABLE FLOATVAL get_number_keyed_int(INTVAL idx) {
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_number(INTERP, item);
+ }
+
+ VTABLE FLOATVAL get_number_keyed(PMC *key) {
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_number(INTERP, item);
}
/*
@@ -299,9 +477,10 @@
*/
VTABLE void set_pmc_keyed_int(INTVAL idx, PMC *val) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
+ const INTVAL n = STATICSELF.elements();
STRING * const fmt = CONST_STRING(INTERP, "\1%d");
+ PMC *list_entry;
+ INTVAL pos;
if (idx < -n)
idx = -idx - n - 1;
@@ -314,12 +493,9 @@
SELF.set_pmc_keyed_str(key, val);
}
else {
- HashBucket * const b = h->bs + idx;
-
- if (!b->key)
- b->key = Parrot_sprintf_s(INTERP, fmt, idx);
-
- b->value = val;
+ list_entry = get_list_item(INTERP, SELF, idx);
+ PARROT_ASSERT(!PMC_IS_NULL(list_entry));
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, val);
}
}
@@ -390,60 +566,26 @@
*/
VTABLE INTVAL exists_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (b->key)
- return 1;
-
- return 0;
+ return (idx >= 0) && (idx < STATICSELF.elements());
}
VTABLE INTVAL exists_keyed(PMC *key) {
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- PMC *item, *next;
- HashBucket *b;
- Hash * const h = (Hash *)SELF.get_pointer();
- INTVAL idx = VTABLE_get_integer(INTERP, key);
- const INTVAL n = h->entries;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (!b->key)
- return 0;
-
- item = (PMC *)b->value;
- next = VTABLE_shift_pmc(INTERP, key);
+ if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
+ /* Don't fetch item prematurely. It's costy */
+ INTVAL intval = VTABLE_get_integer(INTERP, key);
+ PMC * const next = VTABLE_shift_pmc(INTERP, key);
if (!next)
- return 1;
+ return STATICSELF.exists_keyed_int(intval);
- return VTABLE_exists_keyed(INTERP, item, next);
+ return VTABLE_exists_keyed(INTERP, STATICSELF.get_pmc_keyed_int(intval), next);
}
- return SUPER(key);
+ return VTABLE_exists_keyed_str(INTERP, SELF, VTABLE_get_string(INTERP, key));
}
VTABLE INTVAL exists_keyed_str(STRING *key) {
- const Hash * const h = (Hash *)SELF.get_pointer();
- const HashBucket * const b = parrot_hash_get_bucket(INTERP, h, key);
-
- return (b && b->key);
+ return VTABLE_exists_keyed_str(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
}
/*
@@ -459,55 +601,32 @@
*/
VTABLE INTVAL defined_keyed(PMC *key) {
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- Hash * const h = (Hash *)SELF.get_pointer();
- INTVAL idx = VTABLE_get_integer(INTERP, key);
- const INTVAL n = h->entries;
-
- HashBucket *b;
- PMC *item, *next;
-
- if (idx < 0)
- idx += n;
-
- /* XXX non-existent is undefined - is this correct */
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (!b->key)
- return 0;
-
- item = (PMC *)b->value;
- next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return VTABLE_defined(INTERP, item);
-
- return VTABLE_defined_keyed(INTERP, item, next);
- }
+ /* We store list_item (which is defined). So fetch original PMC and check it */
+ PMC * const item = STATICSELF.get_pmc_keyed(key);
+ if (PMC_IS_NULL(item))
+ return 0;
+ return VTABLE_defined(INTERP, item);
+ }
- return SUPER(key);
+ VTABLE INTVAL defined_keyed_str(STRING *key) {
+ PMC * const item = STATICSELF.get_pmc_keyed_str(key);
+ if (PMC_IS_NULL(item))
+ return 0;
+ return VTABLE_defined(INTERP, item);
}
VTABLE INTVAL defined_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
+ PMC * item;
+ /* If item doesn't exists it's undefined */
+ if (!STATICSELF.exists_keyed_int(idx))
return 0;
- b = h->bs + idx;
-
- if (b->key)
- return VTABLE_defined(INTERP, (PMC *)b->value);
+ /* Null is undefined */
+ item = STATICSELF.get_pmc_keyed_int(idx);
+ if (PMC_IS_NULL(item))
+ return 0;
- return 0;
+ return VTABLE_defined(INTERP, item);
}
/*
@@ -525,56 +644,55 @@
*/
VTABLE void delete_keyed(PMC *key) {
- PMC * const next = key_next(INTERP, key);
+ Parrot_OrderedHash_attributes *attrs =
+ PARROT_ORDEREDHASH(SELF);
+ PMC *list_entry, *prev, *next;
+ if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
+ INTVAL intval = VTABLE_get_integer(INTERP, key);
+ PMC * const next = VTABLE_shift_pmc(INTERP, key);
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- if (next) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- VTABLE_delete_keyed(INTERP, item, next);
- return;
- }
+ if (!next)
+ return STATICSELF.delete_keyed_int(intval);
- SELF.delete_keyed_int(VTABLE_get_integer(INTERP, key));
+ return VTABLE_delete_keyed(INTERP, STATICSELF.get_pmc_keyed_int(intval), next);
}
- else {
- if (next) {
- PMC * const item = SELF.get_pmc_keyed_str(VTABLE_get_string(INTERP, key));
- VTABLE_delete_keyed(INTERP, item, next);
- return;
- }
- SELF.delete_keyed_str(VTABLE_get_string(INTERP, key));
- }
- }
-
- VTABLE void delete_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
- if (idx < 0 || idx >= n)
+ list_entry = VTABLE_get_pmc_keyed(INTERP, attrs->hash, key);
+ if (PMC_IS_NULL(list_entry))
return;
- b = h->bs + idx;
+ /* Unlink entry */
+ next = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_NEXT);
+ prev = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_PREV);
+
+ if (attrs->first == list_entry)
+ attrs->first = next;
+
+ if (attrs->last == list_entry)
+ attrs->last = prev;
+
+ /* C<prev> and C<next> are list entries (FPA) */
+ if (!PMC_IS_NULL(prev))
+ VTABLE_set_pmc_keyed_int(INTERP, prev, ORDERED_HASH_ITEM_NEXT, next);
+ if (!PMC_IS_NULL(next))
+ VTABLE_set_pmc_keyed_int(INTERP, next, ORDERED_HASH_ITEM_PREV, prev);
- if (!b)
- return;
-
- b->key = NULL;
- b->value = NULL;
+ /* And finally delete it */
+ return VTABLE_delete_keyed(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
}
VTABLE void delete_keyed_str(STRING *key) {
- const Hash * const h = (Hash *)SELF.get_pointer();
- HashBucket * const b = parrot_hash_get_bucket(INTERP, h, key);
+ return STATICSELF.delete_keyed(box_string(INTERP, key));
+ }
- if (!b)
+ VTABLE void delete_keyed_int(INTVAL idx) {
+ PMC *list_entry;
+ if (!STATICSELF.exists_keyed_int(idx))
return;
- b->key = NULL;
- b->value = NULL;
+ list_entry = get_list_item(INTERP, SELF, idx);
+ STATICSELF.delete_keyed(
+ VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_KEY));
}
/*
@@ -590,18 +708,11 @@
VTABLE PMC *clone() {
PMC * const dest = pmc_new(INTERP, SELF->vtable->base_type);
- Hash * const hash = (Hash *)SELF.get_pointer();
- Hash * const h_dest = (Hash *)VTABLE_get_pointer(INTERP, dest);
- UINTVAL i;
-
- for (i = 0; i <= N_BUCKETS(hash->mask-1); i++) {
- HashBucket * const b = hash->bs + i;
- void * const key = b->key;
-
- if (key)
- parrot_hash_put(INTERP, h_dest, key,
- (void *)VTABLE_clone(INTERP, (PMC *)b->value));
- }
+ Parrot_OrderedHash_attributes *clone_attrs =
+ PARROT_ORDEREDHASH(dest);
+
+ clone_attrs->hash = VTABLE_clone(INTERP, PARROT_ORDEREDHASH(SELF)->hash);
+ find_bounds(INTERP, clone_attrs->hash, &clone_attrs->first, &clone_attrs->last);
return dest;
}
@@ -619,43 +730,35 @@
Used to unarchive the hash.
-Freeze/thaw are inherited from hash. Only thaw.visit is special, as we have to
-preserve key/value order.
-
=cut
*/
VTABLE void visit(visit_info *info) {
- switch (VTABLE_get_integer(INTERP, info)) {
- case VISIT_THAW_NORMAL:
- SUPER(info);
- break;
-
- case VISIT_FREEZE_NORMAL:
- {
- Hash * const hash = (Hash *)SELF.get_pointer();
- const UINTVAL entries = hash->entries;
- UINTVAL i;
-
- for (i = 0; i < entries; i++) {
- HashBucket * const b = hash->bs + i;
-
- if (b) {
- STRING * const key = (STRING *)b->key;
- if (key) {
- VTABLE_push_string(interp, info, key);
- (info->visit_pmc_now)(interp, (PMC *)b->value, info);
- }
- }
- }
- }
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL,
- EXCEPTION_INVALID_OPERATION,
- "unhandled visit action (%d)", VTABLE_get_integer(INTERP, info));
- }
+ VISIT_PMC_ATTR(INTERP, info, SELF, OrderedHash, hash);
+ SUPER(info);
+ }
+
+ VTABLE void thawfinish(visit_info *info) {
+ Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(SELF);
+ find_bounds(INTERP, attrs->hash, &attrs->first, &attrs->last);
+ SUPER(info);
+ }
+
+/*
+
+=item C<get_pmc()>
+
+Get underlying regular Hash. Used in UnManagedStruct.
+
+=cut
+
+*/
+
+ VTABLE PMC* get_pmc() {
+ PMC *hash;
+ GET_ATTR_hash(INTERP, SELF, hash);
+ return hash;
}
}
Modified: trunk/src/pmc/orderedhashiterator.pmc
==============================================================================
--- trunk/src/pmc/orderedhashiterator.pmc Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/src/pmc/orderedhashiterator.pmc Mon Jan 25 13:50:23 2010 (r43586)
@@ -18,12 +18,12 @@
*/
-#include "pmc/pmc_hash.h"
+#include "pmc/pmc_orderedhash.h"
#include "pmc/pmc_hashiteratorkey.h"
pmclass OrderedHashIterator extends Iterator no_ro auto_attrs {
ATTR PMC *pmc_hash; /* the Hash which this Iterator iterates */
- ATTR Hash *parrot_hash; /* Underlying implementation of hash */
+ ATTR PMC *next_entry; /* Next entry to shift/pop */
ATTR INTVAL pos; /* */
ATTR INTVAL elements; /* How many elements left to iterate over */
ATTR INTVAL reverse; /* Direction of iteration. 1 - for reverse iteration */
@@ -44,11 +44,10 @@
(Parrot_OrderedHashIterator_attributes *) PMC_data(SELF);
attrs->pmc_hash = hash;
- attrs->parrot_hash = (Hash*)VTABLE_get_pointer(INTERP, hash);
attrs->pos = 0;
- /* Will be decreased on initial advance_to_next */
- /* XXX Do we really need to support this use-case ? */
- attrs->elements = attrs->parrot_hash->entries;
+ attrs->elements = VTABLE_elements(INTERP, hash);
+ attrs->next_entry = PARROT_ORDEREDHASH(hash)->first;
+ PMC_data(SELF) = attrs;
PObj_custom_mark_SET(SELF);
}
@@ -91,15 +90,17 @@
PARROT_ORDEREDHASHITERATOR(SELF);
/* Restart iterator */
- attrs->elements = attrs->parrot_hash->entries;
+ attrs->elements = VTABLE_elements(INTERP, attrs->pmc_hash);
if (value == ITERATE_FROM_START || value == ITERATE_FROM_START_KEYS) {
- attrs->pos = 0;
- attrs->reverse = 0;
+ attrs->pos = 0;
+ attrs->reverse = 0;
+ attrs->next_entry = PARROT_ORDEREDHASH(attrs->pmc_hash)->first;
return;
}
else if (value == ITERATE_FROM_END) {
- attrs->pos = attrs->elements;
- attrs->reverse = 1;
+ attrs->pos = attrs->elements;
+ attrs->reverse = 1;
+ attrs->next_entry = PARROT_ORDEREDHASH(attrs->pmc_hash)->last;
return;
}
@@ -168,22 +169,18 @@
PARROT_ORDEREDHASHITERATOR(SELF);
PMC *ret;
- HashBucket *bucket;
if (!attrs->elements)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"StopIteration");
/* Get bucket and move to next bucket */
- do {
- bucket = attrs->parrot_hash->bs + attrs->pos++;
- attrs->elements--;
- } while (attrs->elements && !bucket->key);
-
- /* Reuse HashIteratorKey */
- ret = pmc_new(INTERP, enum_class_HashIteratorKey);
- VTABLE_set_pointer_keyed_int(INTERP, ret, 0, attrs->parrot_hash);
- VTABLE_set_pointer_keyed_int(INTERP, ret, 1, bucket);
+ ret = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+ ORDERED_HASH_ITEM_KEY);
+ attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+ ORDERED_HASH_ITEM_NEXT);
+ attrs->pos++;
+ attrs->elements--;
return ret;
}
@@ -204,21 +201,18 @@
PARROT_ORDEREDHASHITERATOR(SELF);
PMC *ret;
- HashBucket *bucket;
if (!attrs->elements)
Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
"StopIteration");
- /* Get bucket and move to next bucket */
- bucket = attrs->parrot_hash->bs + --attrs->pos;
+ ret = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+ ORDERED_HASH_ITEM_KEY);
+ attrs->next_entry = VTABLE_get_pmc_keyed_int(INTERP, attrs->next_entry,
+ ORDERED_HASH_ITEM_PREV);
+ attrs->pos--;
attrs->elements--;
- /* Reuse HashIteratorKey */
- ret = pmc_new(INTERP, enum_class_HashIteratorKey);
- VTABLE_set_pointer_keyed_int(INTERP, ret, 0, attrs->parrot_hash);
- VTABLE_set_pointer_keyed_int(INTERP, ret, 1, bucket);
-
return ret;
}
Modified: trunk/src/pmc/unmanagedstruct.pmc
==============================================================================
--- trunk/src/pmc/unmanagedstruct.pmc Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/src/pmc/unmanagedstruct.pmc Mon Jan 25 13:50:23 2010 (r43586)
@@ -90,9 +90,10 @@
PMC * const types = PARROT_UNMANAGEDSTRUCT(pmc)->init;
if (types->vtable->base_type == enum_class_OrderedHash) {
- Hash * const hash = (Hash *)VTABLE_get_pointer(interp, types);
+ Hash * const hash = (Hash *)VTABLE_get_pointer(interp,
+ VTABLE_get_pmc(interp, types));
HashBucket * const b = parrot_hash_get_bucket(interp, hash,
- VTABLE_get_string(interp, key));
+ hash_key_from_string(interp, hash, VTABLE_get_string(interp, key)));
if (!b)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_KEY_NOT_FOUND,
Modified: trunk/src/pmc_freeze.c
==============================================================================
--- trunk/src/pmc_freeze.c Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/src/pmc_freeze.c Mon Jan 25 13:50:23 2010 (r43586)
@@ -731,7 +731,8 @@
const INTVAL n = Parrot_pmc_array_length(interp, finish_list);
int i;
- for (i = 0; i < n ; ++i) {
+ /* Thaw in reverse order. We have to fully thaw younger PMCs before use them in older */
+ for (i = n-1; i >= 0; --i) {
current = *(PMC**)Parrot_pmc_array_get(interp, finish_list, i, enum_type_PMC);
if (!PMC_IS_NULL(current))
VTABLE_thawfinish(interp, current, info);
Modified: trunk/t/native_pbc/annotations.pbc
==============================================================================
Binary file (source and/or target). No diff available.
Modified: trunk/t/native_pbc/integer_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.
Modified: trunk/t/native_pbc/number_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.
Modified: trunk/t/native_pbc/string_1.pbc
==============================================================================
Binary file (source and/or target). No diff available.
Modified: trunk/t/pmc/orderedhash.t
==============================================================================
--- trunk/t/pmc/orderedhash.t Mon Jan 25 10:57:11 2010 (r43585)
+++ trunk/t/pmc/orderedhash.t Mon Jan 25 13:50:23 2010 (r43586)
@@ -6,7 +6,7 @@
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 28;
+use Parrot::Test tests => 23;
=head1 NAME
@@ -310,16 +310,10 @@
print I0
exists I0, P0["ghi"]
print I0
- exists I0, P0[0]
- print I0
- exists I0, P0[1]
- print I0
- exists I0, P0[2]
- print I0
print "\n"
end
CODE
-101101
+101
OUTPUT
pasm_output_like( <<'CODE', '/[axj]/', "iterate over keys" );
@@ -636,113 +630,6 @@
ok 4
OUTPUT
-pasm_output_is( <<'CODE', <<'OUTPUT', "set/get compound key" );
- new P0, ['OrderedHash']
- set P0["a"], "Foo\n"
- new P1, ['Hash']
- set P1['foo'], "bar\n"
- set P0["b"], P1
- set P2, P0['b'; 'foo']
- print P2
- set P0['b'; 'foo'], "baz\n"
- set P0['b'; 'quux'], "xyzzy\n"
- set P2, P0['b'; 'foo']
- print P2
- set P2, P0['b'; 'quux']
- print P2
- print "--\n"
- set P2, P0[0]
- print P2
- end
-CODE
-bar
-baz
-xyzzy
---
-Foo
-OUTPUT
-
-pasm_output_is( <<'CODE', <<'OUTPUT', "exists compound key" );
- new P0, ['OrderedHash']
- set P0["a"], "Foo"
- new P1, ['Hash']
- set P1['foo'], "bar\n"
- set P0["b"], P1
- set P0['b'; 'quux'], "xyzzy\n"
- exists I0, P0['a']
- print I0
- exists I0, P0['b'; 'foo']
- print I0
- exists I0, P0['b'; 'quux']
- print I0
- exists I0, P0['b'; 'nada']
- print I0
- exists I0, P0['c']
- print I0
- print "\n--\n"
- exists I0, P0[0]
- print I0
- exists I0, P0[1; 'foo']
- print I0
- exists I0, P0[1; 'quux']
- print I0
- exists I0, P0[1; 'nada']
- print I0
- exists I0, P0[2]
- print I0
- print "\n"
- end
-CODE
-11100
---
-11100
-OUTPUT
-
-pasm_output_is( <<'CODE', <<'OUTPUT', "delete compound key" );
- new P0, ['OrderedHash']
- set P0["a"], "Foo"
- new P1, ['Hash']
- set P1['foo'], "bar\n"
- set P0["b"], P1
- set P0['b'; 'quux'], "xyzzy\n"
- delete P0['b'; 'foo']
- exists I0, P0['a']
- print I0
- exists I0, P0['b'; 'foo']
- print I0
- exists I0, P0['b'; 'quux']
- print I0
- exists I0, P0['b'; 'nada']
- print I0
- exists I0, P0['c']
- print I0
- print "\n--\n"
- exists I0, P0[0]
- print I0
- exists I0, P0[1; 'foo']
- print I0
- exists I0, P0[1; 'quux']
- print I0
- exists I0, P0[1; 'nada']
- print I0
- exists I0, P0[2]
- print I0
- print "\n--\n"
- delete P0[1; 'quux']
- exists I0, P0['b'; 'quux']
- print I0
- exists I0, P0[1; 'quux']
- print I0
- print "\n"
- end
-CODE
-10100
---
-10100
---
-00
-OUTPUT
-
pasm_output_is( <<'CODE', <<'OUTPUT', "freeze/thaw 1" );
new P0, ['OrderedHash']
set P0["a"], "Foo\n"
@@ -767,104 +654,6 @@
Bar
OUTPUT
-pasm_output_is( <<'CODE', <<'OUTPUT', "freeze/thaw 2" );
- new P0, ['OrderedHash']
- set P0["a"], "Foo\n"
- new P1, ['Hash']
- set P1['foo'], "bar\n"
- set P0["b"], P1
- set P0['b'; 'quux'], "xyzzy\n"
-
- freeze S0, P0
- thaw P1, S0
- set P2, P1["a"]
- print P2
- set P2, P1[0]
- print P2
- set P2, P1["b";"foo"]
- print P2
- set P2, P1[1; "foo"]
- print P2
- set P2, P1["b";"quux"]
- print P2
- set P2, P1[1; "quux"]
- print P2
-
- end
-CODE
-Foo
-Foo
-bar
-bar
-xyzzy
-xyzzy
-OUTPUT
-
-pir_output_is( <<'CODE', <<'OUTPUT', 'freeze/thaw 3' );
-.sub main :main
- .local string frozen
- frozen = get_frozen_hash()
-
- sweep 1
-
- .local pmc parent
- parent = thaw frozen
- $S0 = parent['a']
- say $S0
-
- $S0 = parent[0]
- say $S0
-
- .local pmc child
- child = parent[1]
- $S0 = child[0]
- say $S0
-
- $S0 = child['foo']
- say $S0
-
- $S0 = parent[1; 'foo']
- say $S0
-
- $S0 = parent['b'; 'foo']
- say $S0
-
- $S0 = parent['b'; 'quux']
- say $S0
-
- $S0 = parent['b'; 2]
- say $S0
- end
-.end
-
-.sub get_frozen_hash
- .local pmc parent
- parent = new ['OrderedHash']
- parent['a'] = 'Foo'
-
- .local pmc child
- child = new ['OrderedHash']
- child['foo'] = 'bar'
- push child, 'baz'
-
- parent['b'] = child
- parent['b'; 'quux'] = 'qaax'
-
- .local string frozen
- frozen = freeze parent
- .return( frozen )
-.end
-CODE
-Foo
-Foo
-bar
-bar
-bar
-bar
-qaax
-qaax
-OUTPUT
-
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
More information about the parrot-commits
mailing list