Author: particle
Date: Tue Apr  3 11:16:04 2007
New Revision: 17961

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

Log:
[pmc] Exporter updates
~ modified behavior to initialize 'globals' with Null PMC
~ started MMD work, but MMD + PCCMETHOD is not yet implemented
~ modified 'add_global' to deal with Null PMC
~ 'import' method complete? needs more tests

Modified: trunk/src/pmc/exporter.pmc
==============================================================================
--- trunk/src/pmc/exporter.pmc  (original)
+++ trunk/src/pmc/exporter.pmc  Tue Apr  3 11:16:04 2007
@@ -8,7 +8,8 @@
 
 =head1 DESCRIPTION
 
-Exports globals from one namespace to another.
+Exports globals from one namespace to another. Exporter always uses
+the typed namespace interface, as outlined in B<PDD21>.
 
 Exporter is not derived from any other PMC, and does not provide any
 standard interface--its inteface consists solely of non-vtable methods.
@@ -32,7 +33,7 @@
 =item C<globals>
 
 The globals to export -- a ResizableStringArray.
-An empty PMC of this type is allocated during initialization.
+A Null PMC is allocated during initialization.
 
 =cut
 
@@ -82,10 +83,10 @@
         PObj_active_destroy_SET(SELF);
 
         /* Set up the object. */
-        exp = mem_sys_allocate_zeroed(sizeof(Parrot_Exporter));
+        exp = mem_sys_allocate_zeroed(sizeof (Parrot_Exporter));
         exp->ns_src  = pmc_new(interp, enum_class_NameSpace);
         exp->ns_dest = pmc_new(interp, enum_class_NameSpace);
-        exp->globals = pmc_new(interp, enum_class_ResizableStringArray);
+        exp->globals = PMCNULL;
         PMC_data(SELF) = exp;
     }
 
@@ -202,30 +203,49 @@
 /*
 
 =item C<PCCMETHOD void
-    globals(PMC *glb_array :optional, int got_glb_array :opt_flag)>
+    globals(PMC *glb :optional, int got_glb :opt_flag)>
 
 Accessor for the array of globals to export (C<globals>.)
-Sets the array if C<glb_array> is passed, otherwise returns the value.
+Sets the array if C<glb> is passed, otherwise returns the value.
+If C<glb> is a String, it is split on ascii whitespace.
+If C<glb> is a FixedStringArray, it is cloned and set.
 
-TODO: need to add some type checking code.
-
-TODO: does not deal with non-array PMCs yet.
+TODO: get MMD working
 
 =cut
 
 */
 
-    PCCMETHOD void globals(PMC *glb_array :optional, int got_glb_array 
:opt_flag) {
+    PCCMETHOD void globals(PMC *glb :optional, int got_glb :opt_flag) {
         Parrot_Exporter *exp = PARROT_EXPORTER(SELF);
         PMC *ret_globals;
 
-        /* TODO deal properly with non-array pmcs */
-        if (got_glb_array) {
-            exp->globals = VTABLE_clone(interp, glb_array);
-        }
-        else {
-            ret_globals = VTABLE_clone(interp, exp->globals);
-            PCCRETURN(PMC *ret_globals);
+        if (got_glb) {
+            if (PMC_IS_NULL(glb)) {
+                exp->globals = PMCNULL;
+            }
+            else {
+/* xxx_MMD_FixedStringArray: { */
+                exp->globals = VTABLE_clone(interp, glb);
+/*                          }
+xxx_MMD_String: {
+                exp->globals = string_split(interp, ' ', glb);
+            }
+xxx_MMD_DEFAULT: {
+                 real_exception(interp, NULL, 0,
+                         "unrecognized type in MMD dispatch");
+             }
+*/
+            }
+         }
+         else {
+            if (PMC_IS_NULL(exp->globals)) {
+                PCCRETURN(PMC *PMCNULL);
+            }
+            else {
+                ret_globals = VTABLE_clone(interp, exp->globals);
+                PCCRETURN(PMC *ret_globals);
+            }
         }
     }
 
@@ -245,6 +265,9 @@
     PCCMETHOD void add_global(PMC *global :optional, int has_global :opt_flag) 
{
         Parrot_Exporter *exp = PARROT_EXPORTER(SELF);
         if (has_global) {
+            if (PMC_IS_NULL(exp->globals))
+                exp->globals = pmc_new(interp, 
enum_class_ResizableStringArray);
+
             VTABLE_push_string(interp, exp->globals,
                     VTABLE_get_string(interp, global));
         }
@@ -261,6 +284,9 @@
 Import C<globals> from the C<src> namespace to the C<dest> namespace.
 If C<src>, C<dest>, or C<globals> are passed, they will override
 the current value.
+C<import> follows the semantics of the C<export_to> method
+of the C<NameSpace> PMC. in particular, if a NULL value is passed
+for C<globals>, the default set of items will be imported.
 Throws an exception upon error.
 
 =cut
@@ -270,16 +296,10 @@
     PCCMETHOD void import(PMC *dest :optional :named["destination"], int 
got_dest :opt_flag,
             PMC *src :optional :named["source"], int got_src :opt_flag,
             PMC *globals :optional :named["globals"], int got_globals 
:opt_flag) {
-/*
- * notes:
- * for each global,
- *   find global in source namespace, throw exception if not found
- *   find global in destination namespace, throw warning if found
- *   store global in destination namespace
- */
 
         Parrot_Exporter *exp = PARROT_EXPORTER(SELF);
         int copy_of_globals;
+        PMC *ns_src, *ns_dest, *ns_globals;
 
         if (got_src)
             PCCINVOKE(interp, SELF, "source", PMC *src);
@@ -288,10 +308,6 @@
         if (got_globals)
             PCCINVOKE(interp, SELF, "globals", PMC *globals);
 
-        if (exp->globals == PMCNULL) {
-            real_exception(interp, NULL, 0, "no globals to import");
-            return;
-        }
         if (exp->ns_src == PMCNULL) {
             real_exception(interp, NULL, 0, "source namespace not set");
             return;
@@ -301,13 +317,17 @@
             return;
         }
 
+        ns_src     = exp->ns_src;
+        ns_dest    = exp->ns_dest;
+        ns_globals = exp->globals;
+
         copy_of_globals = VTABLE_get_integer(interp, exp->globals);
+        PCCINVOKE(interp, ns_src, "export_to", PMC *ns_dest, PMC *ns_globals);
         return;
-        /* TODO for each global, look up in source and alias to dest */
     }
 
 
-}
+} /* end pmclass Exporter */
 
 /*
 

Modified: trunk/t/pmc/exporter.t
==============================================================================
--- trunk/t/pmc/exporter.t      (original)
+++ trunk/t/pmc/exporter.t      Tue Apr  3 11:16:04 2007
@@ -152,32 +152,28 @@
     $P0 = new .Exporter
 
     $P1 = $P0.'globals'()
-    $I0 = does $P1, 'array'
+    $I0 = isnull $P1
     if $I0 goto ok_1
     print 'not '
   ok_1:
-    say 'ok 1 - globals() with no args returns globals array'
-
-    $I0 = $P1
-    if $I0 == 0 goto ok_2
-    print 'not '
-  ok_2:
-    say 'ok 2 - ...which is empty at first'
+    say 'ok 1 - globals() returns PMCNULL upon Exporter init'
 
     # create an array to store globals in
     $P99 = new .ResizableStringArray
 
     $P0.'globals'($P99)
     $P1 = $P0.'globals'()
+    $I0 = does $P1, 'array'
     $I99 = $P99
     $I1 = $P1
-    unless $I1 == $I99 goto nok_3
-    unless $I1 == 0 goto ok_3
-    goto ok_3
-  nok_3:
+    unless $I0 == 1 goto nok_2
+    unless $I1 == $I99 goto nok_2
+    unless $I1 == 0 goto ok_2
+    goto ok_2
+  nok_2:
     print 'not '
-  ok_3:
-    say 'ok 3 - globals() with args sets globals array (empty array)'
+  ok_2:
+    say 'ok 2 - globals() with args sets globals array (empty array)'
 
     $P99 = push 'Alex'
     $P99 = push 'Prince'
@@ -186,36 +182,35 @@
     $P1 = $P0.'globals'()
     $I99 = $P99
     $I1 = $P1
-    unless $I1 == $I99 goto nok_4
-    unless $I1 == 2 goto nok_4
+    unless $I1 == $I99 goto nok_3
+    unless $I1 == 2 goto nok_3
     $S0 = pop $P1
-    unless $S0 == 'Prince' goto nok_4
+    unless $S0 == 'Prince' goto nok_3
     $S0 = pop $P1
-    unless $S0 == 'Alex' goto nok_4
-    goto ok_4
-  nok_4:
+    unless $S0 == 'Alex' goto nok_3
+    goto ok_3
+  nok_3:
     print 'not '
-  ok_4:
-    say 'ok 4 - globals() with args sets globals array (array with two values)'
+  ok_3:
+    say 'ok 3 - globals() with args sets globals array (array with two values)'
 
 
     $P98 = clone $P99
 
-    push_eh ok_5
+    push_eh ok_4
     $P0.'globals'($P99, $P98)
     clear_eh
 
     print 'not '
-  ok_5:
-    say 'ok 5 - globals() with too many args fails'
+  ok_4:
+    say 'ok 4 - globals() with too many args fails'
 
 .end
 CODE
-ok 1 - globals() with no args returns globals array
-ok 2 - ...which is empty at first
-ok 3 - globals() with args sets globals array (empty array)
-ok 4 - globals() with args sets globals array (array with two values)
-ok 5 - globals() with too many args fails
+ok 1 - globals() returns PMCNULL upon Exporter init
+ok 2 - globals() with args sets globals array (empty array)
+ok 3 - globals() with args sets globals array (array with two values)
+ok 4 - globals() with too many args fails
 OUT
 
 
@@ -225,12 +220,7 @@
 
     $P0.'add_global'()
     $P1 = $P0.'globals'()
-    $I0 = does $P1, 'array'
-    unless $I0 goto nok_1
-    $I0 = $P1
-    unless $I0 == 0 goto nok_1
-    goto ok_1
-  nok_1:
+    if null $P1 goto ok_1
     print 'not '
   ok_1:
     say 'ok 1 - add_global() with no args does nothing'
@@ -277,8 +267,9 @@
 ok 4 - add_global() with too many args fails
 OUT
 
+
 ## TODO import
-pir_output_is( <<'CODE', <<'OUT', 'import' );
+pir_output_like( <<'CODE', <<'OUT', 'import - no args' );
 .sub 'test' :main
     $P0 = new .Exporter
 
@@ -287,10 +278,10 @@
 
 .end
 CODE
-ok 1 - import() with no args does nothing
+/^no globals to import\n/
 OUT
 
-# Parrot_free_context
+
 
 
 # Local Variables:

Reply via email to