Permalink
Browse files

[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

git-svn-id: https://svn.parrot.org/parrot/trunk@17961 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information...
1 parent c238f57 commit b29ad29da3848322c67af26e5f9c5d25ceb62156 @particle particle committed Apr 3, 2007
Showing with 80 additions and 69 deletions.
  1. +50 −30 src/pmc/exporter.pmc
  2. +30 −39 t/pmc/exporter.t
View
@@ -8,7 +8,8 @@ src/pmc/exporter.pmc - Export globals from one namespace to another
=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 @@ An empty PMC of this type is allocated upon initialization.
=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 @@ Instantiates an Exporter.
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 @@ Throws an exception if a non-NameSpace PMC is passed.
/*
=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 @@ Sets the array if C<glb_array> is passed, otherwise does nothing.
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 @@ Sets the array if C<glb_array> is passed, otherwise does nothing.
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 @@ Throws an exception upon error.
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 @@ Throws an exception upon error.
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 @@ Throws an exception upon error.
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 */
/*
View
@@ -152,32 +152,28 @@ pir_output_is( <<'CODE', <<'OUT', 'globals' );
$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 @@ pir_output_is( <<'CODE', <<'OUT', 'globals' );
$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 @@ pir_output_is( <<'CODE', <<'OUT', 'add_global' );
$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 3 - add_global() with args adds string to globals array (again)
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 @@ pir_output_is( <<'CODE', <<'OUT', 'import' );
.end
CODE
-ok 1 - import() with no args does nothing
+/^no globals to import\n/
OUT
-# Parrot_free_context
+
# Local Variables:

0 comments on commit b29ad29

Please sign in to comment.