Author: jonathan
Date: Sun Apr 15 14:25:48 2007
New Revision: 18230

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

Log:
[PDD15]: Implement initializing attributes, methods, parents, roles and the 
resolve_method list for both init_pmc and clone_pmc. Add a test for it in the 
init case (clone calls the same code anyway).

Modified: trunk/src/pmc/class.pmc
==============================================================================
--- trunk/src/pmc/class.pmc     (original)
+++ trunk/src/pmc/class.pmc     Sun Apr 15 14:25:48 2007
@@ -183,6 +183,7 @@
     Parrot_Class *class = PARROT_CLASS(self);
     int have_name, have_ns;
     PMC *old_ns;
+    int i;
 
     /* Ensure we actually have some initialization info. */
     if (PMC_IS_NULL(info))
@@ -260,8 +261,71 @@
         Parrot_PCCINVOKE(interp, class->namespace,
             string_from_const_cstring(interp, "set_class", 0),
             "P->", self);
+    
+    /* Initialize resolve_method. */
+    if (VTABLE_exists_keyed_str(interp, info,
+        string_from_const_cstring(interp, "resolve_method", 0))) {
+        /* Set it. */
+        class->resolve_method = VTABLE_get_pmc_keyed_str(interp, info,
+            string_from_const_cstring(interp, "resolve_method", 0));
+    }
+
+    /* Initialize parents, if we have any. */
+    if (VTABLE_exists_keyed_str(interp, info,
+        string_from_const_cstring(interp, "parents", 0))) {
+        /* Loop over parents array and add them. */
+        PMC *parent_list = VTABLE_get_pmc_keyed_str(interp, info,
+            string_from_const_cstring(interp, "parents", 0));
+        int parent_count = VTABLE_elements(interp, parent_list);
+        for (i = 0; i < parent_count; i++) {
+            PMC *parent = VTABLE_get_pmc_keyed_int(interp, parent_list, i);
+            VTABLE_add_parent(interp, self, parent);
+        }
+    }
+
+    /* Initialize roles, if we have any. */
+    if (VTABLE_exists_keyed_str(interp, info,
+        string_from_const_cstring(interp, "roles", 0))) {
+        /* Loop over roles array and compose them. */
+        PMC *role_list = VTABLE_get_pmc_keyed_str(interp, info,
+            string_from_const_cstring(interp, "roles", 0));
+        int role_count = VTABLE_elements(interp, role_list);
+        for (i = 0; i < role_count; i++) {
+            PMC *role = VTABLE_get_pmc_keyed_int(interp, role_list, i);
+            VTABLE_add_role(interp, self, role);
+        }
+    }
+
+    /* Initialize attributes, if we have any. */
+    if (VTABLE_exists_keyed_str(interp, info,
+        string_from_const_cstring(interp, "attributes", 0))) {
+        /* Loop over attributes array and add them. */
+        PMC *attrib_name_list = VTABLE_get_pmc_keyed_str(interp, info,
+            string_from_const_cstring(interp, "attributes", 0));
+        int attrib_count = VTABLE_elements(interp, attrib_name_list);
+        for (i = 0; i < attrib_count; i++) {
+            STRING *attrib_name = VTABLE_get_string_keyed_int(interp,
+                attrib_name_list, i);
+            VTABLE_add_attribute(interp, self, attrib_name, PMCNULL);
+        }
+    }
+
+    /* Initialize methods. */
+    if (VTABLE_exists_keyed_str(interp, info,
+        string_from_const_cstring(interp, "methods", 0))) {
+        /* Get the methods hash. */
+        PMC *methods = VTABLE_get_pmc_keyed_str(interp, info,
+            string_from_const_cstring(interp, "methods", 0));
 
-    /* XXX TODO: initialize resolve, parents, roles, attributes, methods. */
+        /* Iterate over the list of methods. */
+        PMC *iter = VTABLE_get_iter(interp, methods);
+        while (VTABLE_get_bool(interp, iter)) {
+            /* Add the method. */
+            STRING *method_name = VTABLE_shift_string(interp, iter);
+            PMC *method_pmc = VTABLE_get_pmc_keyed_str(interp, methods, 
method_name);
+            VTABLE_add_method(interp, self, method_name, method_pmc);
+        }
+    }
 }
 
 

Modified: trunk/t/pmc/class.t
==============================================================================
--- trunk/t/pmc/class.t (original)
+++ trunk/t/pmc/class.t Sun Apr 15 14:25:48 2007
@@ -6,7 +6,7 @@
 use warnings;
 use lib qw( . lib ../lib ../../lib );
 use Test::More;
-use Parrot::Test tests => 12;
+use Parrot::Test tests => 13;
 
 =head1 NAME
 
@@ -404,6 +404,56 @@
 ok 6 - can modify cloned class
 OUT
 
+pir_output_is( <<'CODE', <<'OUT', 'new with initialization hash' );
+.sub 'test' :main
+    $P0 = new 'Hash'
+
+    # We'll have some attributes...
+    $P1 = new 'ResizablePMCArray'
+    $P1[0] = 'x'
+    $P1[1] = 'y'
+    $P0['attributes'] = $P1
+
+    # And a method.
+    $P1 = new 'Hash'
+    $P2 = find_global 'add'
+    $P1['add'] = $P2
+    $P0['methods'] = $P1
+
+    $P1 = new 'Class', $P0
+    print "ok 1 - created new class with attributes and methods supplied\n"
+
+    # Instantiate and try setting each attribute.
+    $P2 = $P1.'new'()
+    $P3 = new 'Integer'
+    $P3 = 37
+    setattribute $P2, 'x', $P3
+    print "ok 2 - set first attribute\n"
+    $P3 = new 'Integer'
+    $P3 = 5
+    setattribute $P2, 'y', $P3
+    print "ok 3 - set second attribute\n"
+    
+    # Call method.
+    $P3 = $P2.add()
+    print $P3
+    print "\nok 4 - called method\n"
+.end
+.sub add :method
+    $P0 = getattribute self, "x"
+    $P1 = getattribute self, "y"
+    $P2 = new 'Integer'
+    $P2 = $P0 + $P1
+    .return($P2)
+.end
+CODE
+ok 1 - created new class with attributes and methods supplied
+ok 2 - set first attribute
+ok 3 - set second attribute
+42
+ok 4 - called method
+OUT
+
 # Local Variables:
 #   mode: cperl
 #   cperl-indent-level: 4

Reply via email to