Author: jonathan
Date: Fri Jun  8 06:37:48 2007
New Revision: 18876

Modified:
   trunk/include/parrot/pmc.h
   trunk/src/pmc/pmcproxy.pmc
   trunk/t/pmc/pmcproxy.t

Log:
[PDD17] Fill in most of the methods of the PMCProxy PMC. Add a methods slot 
where we'll eventually hang a hash of methods in the PMC, so they can be 
introspected. Add a test to test inspecting the name and namespace of the PMC 
through PMCProxy.

Modified: trunk/include/parrot/pmc.h
==============================================================================
--- trunk/include/parrot/pmc.h  (original)
+++ trunk/include/parrot/pmc.h  Fri Jun  8 06:37:48 2007
@@ -68,6 +68,7 @@
     PMC *_namespace;      /* The namespace it's linked to, if any. */
     PMC *parents;         /* Proxy PMCs of any immediate parent classes. */
     PMC *all_parents;     /* Cached list of ourself and all parents, in MRO 
order. */
+    PMC *methods;         /* PMC's non-vtable methods. Hash of method names to 
invokables. */
 } Parrot_PMCProxy;
 
 /* Macro to access underlying structure of a PMCProxy PMC. */

Modified: trunk/src/pmc/pmcproxy.pmc
==============================================================================
--- trunk/src/pmc/pmcproxy.pmc  (original)
+++ trunk/src/pmc/pmcproxy.pmc  Fri Jun  8 06:37:48 2007
@@ -134,6 +134,191 @@
             pobject_lives(interp, (PObj*)_pmc->all_parents);
     }
 
+/*
+
+=item C<PMC* inspect_str(STRING *what)>
+
+Provides introspection of a specific piece of information about the PMC. The
+available information is:
+
+=over 8
+
+=item name
+
+String PMC containing the name of the PMC
+
+=item namespce
+
+NameSpace PMC of the the namespace attached to the PMC
+
+=item methods
+
+Hash keyed on method name, value is an invokable PMC
+
+=item parents
+
+Array of PMCProxy PMCs representing the direct parents of this class.
+
+=back
+
+=cut
+
+*/
+    PMC* inspect_str(STRING *what)
+    {
+        Parrot_PMCProxy *_pmc = PARROT_PMCPROXY(SELF);
+
+        /* What should we return? */
+        PMC          *found  = PMCNULL;
+
+        if (string_equal(interp, what, CONST_STRING(interp, "name")) == 0) {
+            found = pmc_new(interp, enum_class_String);
+            VTABLE_set_string_native(interp, found, _pmc->name);
+        }
+        else if (string_equal(interp, what, CONST_STRING(interp, "namespace")) 
== 0) {
+            /* Should not clone this. */
+            return _pmc->_namespace;
+        }
+        else if (string_equal(interp, what, CONST_STRING(interp, "methods")) 
== 0) {
+            found = _pmc->methods;
+        }
+        else if (string_equal(interp, what, CONST_STRING(interp, "parents")) 
== 0) {
+            found = _pmc->parents;
+        }
+        else {
+            real_exception(interp, NULL, INVALID_OPERATION,
+                "Unknown introspection value '%S'", what);
+        }
+
+        /* Clone and return. */
+        return PMC_IS_NULL(found) ? PMCNULL : VTABLE_clone(interp, found);
+    }
+
+/*
+
+=item C<PMC* inspect()>
+
+Returns a Hash describing the PMC, with key/value pairs as described in
+inspect_str.
+
+=cut
+
+*/
+    PMC* inspect()
+    {
+        /* Create a hash, then use inspect_str to get all of the data to
+         * fill it up with. */
+        PMC *metadata = pmc_new(interp, enum_class_Hash);
+        VTABLE_set_pmc_keyed_str(interp, metadata, CONST_STRING(interp, 
"name"),
+            VTABLE_inspect_str(interp, SELF, CONST_STRING(interp, "name")));
+        VTABLE_set_pmc_keyed_str(interp, metadata, CONST_STRING(interp, 
"namespace"),
+            VTABLE_inspect_str(interp, SELF, CONST_STRING(interp, 
"namespace")));
+        VTABLE_set_pmc_keyed_str(interp, metadata, CONST_STRING(interp, 
"methods"),
+            VTABLE_inspect_str(interp, SELF, CONST_STRING(interp, "methods")));
+        VTABLE_set_pmc_keyed_str(interp, metadata, CONST_STRING(interp, 
"parents"),
+            VTABLE_inspect_str(interp, SELF, CONST_STRING(interp, "parents")));
+        return metadata;
+    }
+
+/*
+
+=item C<STRING* name()>
+
+Gets the name of the PMC.
+
+=cut
+
+*/
+    PCCMETHOD void name() {
+        Parrot_PMCProxy *_pmc = PARROT_PMCPROXY(SELF);
+        STRING *ret_name = _pmc->name;
+        PCCRETURN(STRING *ret_name);
+    }
+
+/*
+
+=item C<void pmc_namespace()>
+
+Gets the namespace that this class is attached to.
+
+=cut
+
+*/
+    PCCMETHOD void pmc_namespace() {
+        Parrot_PMCProxy *_pmc = PARROT_PMCPROXY(SELF);
+        PMC *ret_namespace = _pmc->_namespace;
+        PCCRETURN(PMC *ret_namespace);
+    }
+
+/*
+
+=item C<void new(PMC *args)>
+
+Creates an instance of the PMC.
+
+=cut
+
+*/
+    PCCMETHOD void new(PMC *args :optional, int got_args :opt_flag) {
+        Parrot_PMCProxy *_pmc = PARROT_PMCPROXY(SELF);
+        PMC *created;
+        if (got_args)
+            created = pmc_new_init(interp, _pmc->id, args);
+        else
+            created = pmc_new(interp, _pmc->id);
+        PCCRETURN(PMC *created);
+    }
+
+/*
+
+=item C<void methods()>
+
+Return a hash where the keys are method names and the values are methods.
+
+=cut
+
+*/
+    PCCMETHOD void methods() {
+        PMC *ret_methods = VTABLE_inspect_str(interp, SELF, 
CONST_STRING(interp, "methods"));
+        PCCRETURN(PMC *ret_methods);
+    }
+
+/*
+
+=item C<void parents()>
+
+Return the parents array PMC.
+
+=cut
+
+*/
+    PCCMETHOD void parents() {
+        PMC *ret_parents = VTABLE_inspect_str(interp, SELF, 
CONST_STRING(interp, "parents"));
+        PCCRETURN(PMC *ret_parents);
+    }
+
+/*
+
+=item C<void inspect(STRING *what :optional)>
+
+Gets all introspection data for the PMC or, if the optional string
+parameter is supplied, a particular item of introspection data.
+
+=cut
+
+*/
+    PCCMETHOD void inspect(STRING *what :optional, int got_what :opt_flag) {
+        PMC *found;
+
+        /* Just delegate to the appropriate vtable method. */
+        if (got_what)
+            found = VTABLE_inspect_str(interp, SELF, what);
+        else
+            found = VTABLE_inspect(interp, SELF);
+
+        PCCRETURN(PMC *found);
+    }
+
 } /* END pmclass */
 
 /*

Modified: trunk/t/pmc/pmcproxy.t
==============================================================================
--- trunk/t/pmc/pmcproxy.t      (original)
+++ trunk/t/pmc/pmcproxy.t      Fri Jun  8 06:37:48 2007
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 2;
+use Parrot::Test tests => 3;
 
 =head1 NAME
 
@@ -60,6 +60,36 @@
 ok 2 - isa $P0, 'PMCProxy'
 OUT
 
+pir_output_is( <<'CODE', <<'OUT', 'Proxy PMC supplies name, namespace' );
+.sub 'test' :main
+push_eh nok_1
+    $P0 = get_class 'NameSpace'
+    clear_eh
+    goto ok_1
+nok_1:
+    print "not "
+ok_1:
+    print "ok 1 - get_class returned something\n"
+
+    $S1 = $P0.'name'()
+    print $S1
+    print "\n"
+    print "ok 2 - got name\n"
+
+    $P1 = $P0.'pmc_namespace'()
+    $S1 = $P1
+    print $S1
+    print "\n"
+    print "ok 3 - got namespace\n"
+.end
+CODE
+ok 1 - get_class returned something
+NameSpace
+ok 2 - got name
+NameSpace
+ok 3 - got namespace
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Reply via email to