Author: particle
Date: Tue May  1 16:41:53 2007
New Revision: 18382

Modified:
   trunk/src/pmc/namespace.pmc
   trunk/t/pmc/namespace.t

Changes in other areas also in this revision:
Modified:
   trunk/docs/pdds/pdd21_namespaces.pod

Log:
[pmc]: added functionality to NameSpace PMC 'export_to' method
~ can now accept a hash argument, which allows an object to be exported with a 
different name
~ updated spec, implementation, and tests

Modified: trunk/src/pmc/namespace.pmc
==============================================================================
--- trunk/src/pmc/namespace.pmc (original)
+++ trunk/src/pmc/namespace.pmc Tue May  1 16:41:53 2007
@@ -593,35 +593,101 @@
 
 =item C<METHOD void export_to(PMC* dest, PMC* what)>
 
-Export items from this NameSpace into the C<dest> NameSpace. C<what>
-is an array of (string) names to be exported.
+Export items from this NameSpace into the C<dest> NameSpace. The items to
+export are named in C<what>, which may be an array of strings, a hash, or null.
+If C<what> is an array of strings, interpretation of items in an array follows
+the conventions of the source (exporting) namespace.
+If C<what> is a hash, the keys correspond to the names in the source namespace,
+and the values correspond to the names in the destination namespace.
+if a hash value is null or an empty string, the name in the hash key is used.
+A null C<what> requests the 'default' set of items.
+Any other type passed in C<what> throws an exception.
+
+NOTE: exporting 'default' set of items is not yet implemented.
 
 =cut
 
 */
 
     METHOD void export_to(PMC* dest, PMC* what) {
-        INTVAL i, n;
+        STRING *s_hash  = CONST_STRING(interp, "hash");
+        STRING *s_array = CONST_STRING(interp, "array");
 
         if (PMC_IS_NULL(dest)) {
             real_exception(interp, NULL, 0,
                     "destination namespace not specified");
             return;
         }
+
         if (PMC_IS_NULL(what) || !VTABLE_elements(interp, what)) {
             real_exception(interp, NULL, 0,
-                    "exporting default object set not yet specified");
+                    "exporting default object set not yet implemented");
             return;
         }
 
-        n = VTABLE_elements(INTERP, what);
-        for (i = 0; i < n; ++i) {
-            STRING *name;
-            PMC *el;
-
-            name = VTABLE_get_string_keyed_int(INTERP, what, i);
-            el = VTABLE_get_pmc_keyed_str(INTERP, SELF, name);
-            VTABLE_set_pmc_keyed_str(INTERP, dest, name, el);
+        /* if "what" does "hash", we extract string key/value pairs,
+         * lookup the object with the name specified in the key,
+         * and export it with the name specified as value. */
+        if (VTABLE_does(INTERP, what, s_hash)) {
+            PMC * const  iter = VTABLE_get_iter(interp, what);
+            const INTVAL n    = VTABLE_elements(interp, what);
+            INTVAL       i;
+
+            for (i = 0; i < n; ++i) {
+                STRING *src_name;
+                STRING *dest_name;
+                PMC    *object;
+
+                src_name = VTABLE_shift_string(interp, iter);
+                if (STRING_IS_NULL(src_name) || STRING_IS_EMPTY(src_name)) {
+                    real_exception(interp, NULL, 0, "source object name not 
specified");
+                    return;
+                }
+
+                dest_name = VTABLE_get_string_keyed_str(interp, what, 
src_name);
+                if (STRING_IS_NULL(dest_name) || STRING_IS_EMPTY(dest_name)) {
+                    dest_name = src_name;
+                }
+
+                object = VTABLE_get_pmc_keyed_str(interp, SELF, src_name);
+                if (PMC_IS_NULL(object)) {
+                    real_exception(interp, NULL, 0,
+                            "object '%s' not found in current namespace",
+                            string_to_cstring(interp, src_name));
+                    return;
+                }
+
+                VTABLE_set_pmc_keyed_str(interp, dest, dest_name, object);
+            }
+        }
+        else if (VTABLE_does(INTERP, what, s_array)) {
+            const INTVAL n = VTABLE_elements(interp, what);
+            INTVAL i;
+
+            for (i = 0; i < n; ++i) {
+                STRING *name;
+                PMC    *object;
+
+                name = VTABLE_get_string_keyed_int(interp, what, i);
+                if (STRING_IS_NULL(name) || STRING_IS_EMPTY(name)) {
+                    real_exception(interp, NULL, 0, "object name not 
specified");
+                    return;
+                }
+
+                object = VTABLE_get_pmc_keyed_str(interp, SELF, name);
+                if (PMC_IS_NULL(object)) {
+                    real_exception(interp, NULL, 0,
+                            "object '%s' not found in current namespace",
+                            string_to_cstring(interp, name));
+                    return;
+                }
+
+                VTABLE_set_pmc_keyed_str(interp, dest, name, object);
+            }
+        }
+        else {
+            real_exception(interp, NULL, 0,
+                    "can't handle argument of type %s", 
what->vtable->base_type);
         }
     }
 

Modified: trunk/t/pmc/namespace.t
==============================================================================
--- trunk/t/pmc/namespace.t     (original)
+++ trunk/t/pmc/namespace.t     Tue May  1 16:41:53 2007
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 56;
+use Parrot::Test tests => 59;
 use Parrot::Config;
 
 =head1 NAME
@@ -703,7 +703,7 @@
 OUTPUT
 
 pir_output_like(
-    <<'CODE', <<'OUTPUT', 'export_to() with null array exports default boject 
set !!!UNSPECIFIED!!!' );
+    <<'CODE', <<'OUTPUT', 'export_to() with null exports default object set 
!!!UNSPECIFIED!!!' );
 .sub 'test' :main
     .local pmc nsa, nsb, ar
 
@@ -717,11 +717,11 @@
 .sub 'foo'
 .end
 CODE
-/^exporting default object set not yet specified\n/
+/^exporting default object set not yet implemented\n/
 OUTPUT
 
 pir_output_like(
-    <<'CODE', <<'OUTPUT', 'export_to() with empty array exports default boject 
set !!!UNSPECIFIED!!!' );
+    <<'CODE', <<'OUTPUT', 'export_to() with empty array exports default object 
set !!!UNSPECIFIED!!!' );
 .sub 'test' :main
     .local pmc nsa, nsb, ar
 
@@ -735,10 +735,28 @@
 .sub 'foo'
 .end
 CODE
-/^exporting default object set not yet specified\n/
+/^exporting default object set not yet implemented\n/
 OUTPUT
 
-pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success" );
+pir_output_like(
+    <<'CODE', <<'OUTPUT', 'export_to() with empty hash exports default object 
set !!!UNSPECIFIED!!!' );
+.sub 'test' :main
+    .local pmc nsa, nsb, ar
+
+    ar = new .Hash
+    nsa = get_namespace
+    nsb = get_namespace ['B']
+    nsb.'export_to'(nsa, ar)
+.end
+
+.namespace ['B']
+.sub 'foo'
+.end
+CODE
+/^exporting default object set not yet implemented\n/
+OUTPUT
+
+pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success with array" );
 .HLL 'A', ''
 .sub main :main
     a_foo()
@@ -761,6 +779,54 @@
 b_foo
 OUTPUT
 
+pir_output_is( <<"CODE", <<'OUTPUT', "export_to -- success with hash (empty 
value)" );
+.HLL 'A', ''
+.sub main :main
+    a_foo()
+    load_bytecode "$temp_b.pir"
+    .local pmc nsr, nsa, nsb, ar
+    ar = new .Hash
+    ar["b_foo"] = ""
+    nsr = get_root_namespace
+    nsa = nsr['a']
+    nsb = nsr['b']
+    nsb."export_to"(nsa, ar)
+    b_foo()
+.end
+
+.sub a_foo
+    print "a_foo\\n"
+.end
+CODE
+a_foo
+b_foo
+OUTPUT
+
+pir_output_like( <<"CODE", <<'OUTPUT', "export_to -- success with hash (and 
value)" );
+.HLL 'A', ''
+.sub main :main
+    a_foo()
+    load_bytecode "$temp_b.pir"
+    .local pmc nsr, nsa, nsb, ar
+    ar = new .Hash
+    ar["b_foo"] = "c_foo"
+    nsr = get_root_namespace
+    nsa = nsr['a']
+    nsb = nsr['b']
+    nsb."export_to"(nsa, ar)
+    c_foo()
+    b_foo()
+.end
+
+.sub a_foo
+    print "a_foo\\n"
+.end
+CODE
+/^a_foo
+b_foo
+Null PMC access in invoke\(\)/
+OUTPUT
+
 pir_output_is( <<'CODE', <<'OUTPUT', "get_parent" );
 .sub main :main
     .local pmc ns

Reply via email to