Author: leo
Date: Wed Mar 8 07:52:15 2006
New Revision: 11824
Modified:
trunk/src/ops/experimental.ops
trunk/src/pmc/namespace.pmc
trunk/t/pmc/namespace.t
Log:
Namespaces 11 - get_namespace Px, Py
* implement get_namespace opcode variants
* test
Modified: trunk/src/ops/experimental.ops
==============================================================================
--- trunk/src/ops/experimental.ops (original)
+++ trunk/src/ops/experimental.ops Wed Mar 8 07:52:15 2006
@@ -238,7 +238,8 @@
=item B<get_namespace>(out PMC, in KEY)
-Get the specified currrent namespace.
+Get the specified namespace. $2 is either an array of names or a key.
+If the namespace doesn't exist, $1 is set to PMCNULL.
=item B<find_global>(out PMC, in KEY, in STR)
@@ -253,6 +254,18 @@
goto NEXT();
}
+op get_namespace(out PMC, in PMC) {
+ PMC *ns_root = interpreter->stash_hash;
+ $1 = VTABLE_get_pmc_keyed(interpreter, ns_root, $2);
+ goto NEXT();
+}
+
+op get_namespace(out PMC, in KEY) {
+ PMC *ns_root = interpreter->stash_hash;
+ $1 = VTABLE_get_pmc_keyed(interpreter, ns_root, $2);
+ goto NEXT();
+}
+
op find_global(out PMC, in KEY, in STR) {
$1 = Parrot_find_global_p(interpreter, $2, $3);
goto NEXT();
Modified: trunk/src/pmc/namespace.pmc
==============================================================================
--- trunk/src/pmc/namespace.pmc (original)
+++ trunk/src/pmc/namespace.pmc Wed Mar 8 07:52:15 2006
@@ -61,6 +61,11 @@
If C<key> is a simple key, it works like above. If C<key> is an array
of strings or a chained key, add all components to the namespace.
+=item C<PMC* get_pmc_keyed(PMC *key)>
+
+Return the given namespace or PMCNULL. C<key> is either an array of
+strings, or a possibly nested key.
+
=cut
*/
@@ -84,6 +89,40 @@
}
}
+ /* XXX Hash would return Undef, which is probably wrong */
+ PMC* get_pmc_keyed_str (STRING* key) {
+ HashBucket *b = hash_get_bucket(INTERP,
+ (Hash*) PMC_struct_val(SELF), key);
+ return b->value;
+ }
+
+ PMC* get_pmc_keyed(PMC *key) {
+ PMC *ns = SELF;
+ STRING *part;
+ INTVAL i, n;
+
+ if (key->vtable->base_type == enum_class_Key) {
+ while (key) {
+ part = key_string(INTERP, key);
+ ns = VTABLE_get_pmc_keyed_str(INTERP, ns, part);
+ if (!ns)
+ return PMCNULL;
+ key = key_next(INTERP, key);
+ }
+ return ns;
+ }
+ n = VTABLE_elements(INTERP, key);
+ if (!n)
+ return PMCNULL;
+ for (i = 0; i < n; ++i) {
+ part = VTABLE_get_string_keyed_int(INTERP, key, i);
+ ns = VTABLE_get_pmc_keyed_str(INTERP, ns, part);
+ if (!ns)
+ return PMCNULL;
+ }
+ return ns;
+ }
+
/*
=item C<STRING* get_string()>
Modified: trunk/t/pmc/namespace.t
==============================================================================
--- trunk/t/pmc/namespace.t (original)
+++ trunk/t/pmc/namespace.t Wed Mar 8 07:52:15 2006
@@ -6,7 +6,7 @@
use warnings;
use lib qw( . lib ../lib ../../lib );
use Test::More;
-use Parrot::Test tests => 20;
+use Parrot::Test tests => 21;
=head1 NAME
@@ -430,3 +430,42 @@
3
::parrot::Foo
OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "get_namespace_p_p, getnamespace_p_kc");
+.sub main :main
+ .include "interpinfo.pasm"
+ $P0 = interpinfo .INTERPINFO_NAMESPACE_ROOT
+ $P1 = $P0["parrot"]
+ $P3 = new .NameSpace
+ $P1["Foo"] = $P3
+ # fetch w array
+ $P1 = new .FixedStringArray
+ $P1 = 2
+ $P1[0] = 'parrot'
+ $P1[1] = 'Foo'
+ $P2 = get_namespace $P1
+ $P2 = $P2.'name'()
+ $I2 = elements $P2
+ print $I2
+ print "\n"
+ $S0 = join '::', $P2
+ print $S0
+ print "\n"
+ # fetch w key
+ $P2 = get_namespace ["parrot";"Foo"]
+ $P2 = $P2.'name'()
+ $I2 = elements $P2
+ print $I2
+ print "\n"
+ $S0 = join '::', $P2
+ print $S0
+ print "\n"
+.end
+# namespace root doesnt have a name
+# XXX should the root namespace be included?
+CODE
+3
+::parrot::Foo
+3
+::parrot::Foo
+OUTPUT