cvsuser     04/12/20 05:10:21

  Modified:    dynclasses pybuiltin.pmc pyclass.pmc pydict.pmc pyint.pmc
                        pylist.pmc pynone.pmc pyobject.pmc pyproxyclass.pmc
                        pyproxytype.pmc pytype.pmc
               languages/python README
  Log:
  implement __new__
  
  Revision  Changes    Path
  1.26      +42 -11    parrot/dynclasses/pybuiltin.pmc
  
  Index: pybuiltin.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pybuiltin.pmc,v
  retrieving revision 1.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- pybuiltin.pmc     18 Dec 2004 15:39:13 -0000      1.25
  +++ pybuiltin.pmc     20 Dec 2004 13:10:18 -0000      1.26
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pybuiltin.pmc,v 1.25 2004/12/18 15:39:13 rubys Exp $
  +$Id: pybuiltin.pmc,v 1.26 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -31,13 +31,15 @@
   static INTVAL dynclass_PyList;
   static INTVAL dynclass_PyLong;
   static INTVAL dynclass_PyNone;
  +static INTVAL dynclass_PyProxyType;
   static INTVAL dynclass_PyString;
   static INTVAL dynclass_PyTuple;
   
  +static STRING *BASES;
   static STRING *HEX;
  +static STRING *NAME;
   static STRING *OCT;
   static STRING *PYOBJECT;
  -static STRING *BASES;
   
   extern PMC* Parrot_Hash_get_iter(Interp* interpreter, PMC* pmc);
   
  @@ -46,12 +48,37 @@
   PMC* Parrot_lib_python_group_init(Interp* interpreter, PMC *lib_pmc);
   void Parrot_PyBuiltin___load__(Interp* interpreter, PMC* pmc);
   
  -PMC*
  -Parrot_lib_python_group_init(Interp* interpreter, PMC *lib_pmc)
  -{
  +PMC* Parrot_lib_python_group_init(Interp* interpreter, PMC *lib_pmc) {
       Parrot_PyBuiltin___load__(interpreter, NULL);
       return lib_pmc;
   }
  +
  +static PMC* make_type(Interp* interpreter, INTVAL class, STRING* name) {
  +    STRING *pmcname = Parrot_base_vtables[class]->whoami;
  +    PMC *type = pmc_new(interpreter, dynclass_PyProxyType);
  +    PMC *nameprop = pmc_new(interpreter, dynclass_PyString);
  +    PMC *stash, *iter, *item;
  +    STRING *key;
  +    INTVAL n, j;
  +
  +    stash = Parrot_find_global(interpreter, pmcname, NULL);
  +    if (!stash) internal_exception(1, "Can't find methods");
  +
  +    /* For each, extract the key and item, and store in the scratchpad */
  +    iter = Parrot_Hash_get_iter(interpreter, stash);
  +    n = VTABLE_elements(interpreter, stash);
  +    for (j = 0; j < n; ++j) {
  +        key = VTABLE_shift_string(interpreter, iter);
  +        item = VTABLE_get_pmc_keyed_str(interpreter, stash, key);
  +        VTABLE_add_method(interpreter, type, key, item);
  +    }
  +
  +    VTABLE_set_string_native(interpreter, nameprop, name);
  +    VTABLE_setprop(interpreter, type, NAME, nameprop);
  +
  +    return type;
  +}
  +
   pmclass PyBuiltin dynpmc group python_group {
   /*
   
  @@ -76,11 +103,13 @@
               dynclass_PyList      = Parrot_PMC_typenum(INTERP, "PyList");
               dynclass_PyLong      = Parrot_PMC_typenum(INTERP, "PyLong");
               dynclass_PyNone      = Parrot_PMC_typenum(INTERP, "PyNone");
  +            dynclass_PyProxyType = Parrot_PMC_typenum(INTERP, "PyProxyType");
               dynclass_PyString    = Parrot_PMC_typenum(INTERP, "PyString");
               dynclass_PyTuple     = Parrot_PMC_typenum(INTERP, "PyTuple");
   
               BASES = const_string(INTERP, "__bases__");
               HEX = const_string(INTERP, "__hex__");
  +            NAME = const_string(INTERP, "__name__");
               OCT = const_string(INTERP, "__oct__");
               PYOBJECT = const_string(INTERP, "PyObject");
           }
  @@ -107,7 +136,7 @@
   
       METHOD void __load__() {
           STRING *name, *key;
  -        PMC *stash, *iter, *item, *pad, *temp;
  +        PMC *stash, *iter, *item, *pad, *temp, *parent;
           INTVAL j, n;
   
           /* Already init'ed? */
  @@ -173,15 +202,17 @@
           scratchpad_store_by_name(INTERP, pad, 0, key, item);
   
           /* Class objects */
  -        /* TODO: convert this to instances of <type> */
  +        key = const_string(INTERP, "object");
  +        parent = make_type(INTERP, dynclass_PyObject, key);
  +
           key = const_string(INTERP, "dict");
  -        item = pmc_new(INTERP, dynclass_PyDict);
  +        item = make_type(INTERP, dynclass_PyDict, key);
  +        VTABLE_setprop(INTERP, item, BASES, parent);
           scratchpad_store_by_name(INTERP, pad, 0, key, item);
   
  -        /* TODO: convert this to instances of <type> */
           key = const_string(INTERP, "int");
  -        item = pmc_new(INTERP, dynclass_PyInt);
  -        VTABLE_set_integer_native(INTERP, item, 15);
  +        item = make_type(INTERP, dynclass_PyInt, key);
  +        VTABLE_setprop(INTERP, item, BASES, parent);
           scratchpad_store_by_name(INTERP, pad, 0, key, item);
   
           /* TODO: convert this to instances of <type> */
  
  
  
  1.15      +5 -2      parrot/dynclasses/pyclass.pmc
  
  Index: pyclass.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pyclass.pmc,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- pyclass.pmc       18 Dec 2004 10:52:46 -0000      1.14
  +++ pyclass.pmc       20 Dec 2004 13:10:18 -0000      1.15
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pyclass.pmc,v 1.14 2004/12/18 10:52:46 rubys Exp $
  +$Id: pyclass.pmc,v 1.15 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -30,7 +30,10 @@
   static STRING *REPR;
   static STRING *STR;
   
  -static struct parrot_regs_t *
  +struct parrot_regs_t *
  +Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub);
  +
  +struct parrot_regs_t *
   Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub)
   {
       opcode_t offset, *dest;
  
  
  
  1.12      +5 -13     parrot/dynclasses/pydict.pmc
  
  Index: pydict.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pydict.pmc,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- pydict.pmc        18 Dec 2004 15:08:20 -0000      1.11
  +++ pydict.pmc        20 Dec 2004 13:10:18 -0000      1.12
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pydict.pmc,v 1.11 2004/12/18 15:08:20 rubys Exp $
  +$Id: pydict.pmc,v 1.12 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -375,27 +375,20 @@
   
   /*
   
  -=item C<void* invoke(void *next)>
  +=item C<PMC* "__new__"(PMC *cls, PMC *source)>
   
   Create a new dictionary from a sequence
   
   =cut
   
  -TODO: move this to the dict type as this is meant to be a class method
  -not an instance method.
  -
   */
   
  -    void* invoke(void *next) {
  +    METHOD PMC* __new__(PMC *cls, PMC *source) {
           PMC *dict = pmc_new(INTERP, dynclass_PyDict);
  -        PMC *source = REG_PMC(5);
           PMC *iter;
           INTVAL argc = REG_INT(3);
   
  -        REG_INT(3) = 1;
  -        REG_PMC(5) = dict;
  -
  -        if (argc == 0) return next;
  +        if (argc == 1) return dict;
   
           if (source->vtable->base_type == dynclass_PyDict) {
               iter = VTABLE_get_iter(INTERP, source);
  @@ -426,8 +419,7 @@
               }
           }
   
  -
  -        return next;
  +        return dict;
       }
   
   /*
  
  
  
  1.13      +14 -32    parrot/dynclasses/pyint.pmc
  
  Index: pyint.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pyint.pmc,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- pyint.pmc 18 Dec 2004 03:51:47 -0000      1.12
  +++ pyint.pmc 20 Dec 2004 13:10:18 -0000      1.13
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pyint.pmc,v 1.12 2004/12/18 03:51:47 rubys Exp $
  +$Id: pyint.pmc,v 1.13 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -27,8 +27,6 @@
   static INTVAL dynclass_PyLong;
   static INTVAL dynclass_PyString;
   
  -static PMC* base_class;
  -
   static void
   overflow(Interp *interpreter, PMC *self, INTVAL b, PMC *dest, int mmd)
   {
  @@ -82,9 +80,6 @@
               dynclass_PyFloat   = Parrot_PMC_typenum(INTERP, "PyFloat");
               dynclass_PyLong    = Parrot_PMC_typenum(INTERP, "PyLong");
               dynclass_PyString  = Parrot_PMC_typenum(INTERP, "PyString");
  -
  -            /* TODO: make Int have a real base class */
  -            base_class = pmc_new(INTERP, dynclass_PyInt);
           }
       }
   
  @@ -584,20 +579,6 @@
   
   /*
   
  -=item C<PMC *get_class()>
  -
  -Return the class of this object.
  -
  -=cut
  -
  -*/
  -
  -    PMC* get_class() {
  -        return base_class;
  -    }
  -
  -/*
  -
   =item C<INTVAL get_integer()>
   
   Returns the integer value of the integer.
  @@ -654,32 +635,28 @@
   
   /*
   
  -=item C<void* invoke(void *next)>
  +=item C<PMC* "__new__"(PMC *class, PMC *source)>
   
   Create a new integer
   
   =cut
   
  -TODO: move this to the int type as this is meant to be a class method
  -not an instance method.
  -
   */
   
  -    void* invoke(void *next) {
  +    METHOD PMC* __new__(PMC *class, PMC *source) {
           INTVAL argc = REG_INT(3);
  -        PMC *source = REG_PMC(5);
   
           PMC * ret = pmc_new(INTERP, dynclass_PyInt);
   
  -        REG_INT(3) = 1;
  -        REG_PMC(5) = ret;
  +        /* XXX: quick hack: class method called directly */
  +        if (argc == 3 && class == SELF) source = REG_PMC(7);
   
  -        if (argc > 0) {
  +        if (argc > 1) {
               INTVAL ivalue = VTABLE_get_integer(INTERP, source);
               VTABLE_set_integer_native(INTERP, ret, ivalue);
           }
   
  -        return next;
  +        return ret;
       }
   
   /*
  @@ -693,8 +670,13 @@
   */
   
       INTVAL is_equal (PMC* value) {
  -        return (INTVAL)(PMC_int_val(SELF) ==
  -            VTABLE_get_integer(INTERP, value));
  +MMD_PyNone: {
  +            return 0;
  +        }
  +MMD_DEFAULT: {
  +            return (INTVAL)(PMC_int_val(SELF) ==
  +                VTABLE_get_integer(INTERP, value));
  +        }
       }
   
   /*
  
  
  
  1.10      +4 -4      parrot/dynclasses/pylist.pmc
  
  Index: pylist.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pylist.pmc,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- pylist.pmc        18 Dec 2004 03:51:47 -0000      1.9
  +++ pylist.pmc        20 Dec 2004 13:10:18 -0000      1.10
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pylist.pmc,v 1.9 2004/12/18 03:51:47 rubys Exp $
  +$Id: pylist.pmc,v 1.10 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -68,7 +68,7 @@
   
   /*
   
  -=item C<void "append" (PMC* value)>
  +=item C<void "append" (PMC* self, PMC* value)>
   
   Extends the array by adding an element of value C<*value> to the end of
   the array.
  @@ -77,8 +77,8 @@
   
   */
   
  -    METHOD void append (PMC* value) {
  -        VTABLE_push_pmc(INTERP, SELF, value);
  +    METHOD void append (PMC* self, PMC* value) {
  +        VTABLE_push_pmc(INTERP, self, value);
       }
   
   /*
  
  
  
  1.3       +20 -1     parrot/dynclasses/pynone.pmc
  
  Index: pynone.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pynone.pmc,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- pynone.pmc        28 Nov 2004 17:27:43 -0000      1.2
  +++ pynone.pmc        20 Dec 2004 13:10:18 -0000      1.3
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pynone.pmc,v 1.2 2004/11/28 17:27:43 rubys Exp $
  +$Id: pynone.pmc,v 1.3 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -57,6 +57,25 @@
   
   /*
   
  +=item C<INTVAL is_equal (PMC* value)>
  +
  +The C<==> operation.
  +
  +=cut
  +
  +*/
  +
  +    INTVAL is_equal (PMC* value) {
  +MMD_PyNone: {
  +            return 1;
  +        }
  +MMD_DEFAULT: {
  +            return 0;
  +        }
  +    }
  +
  +/*
  +
   =back
   
   =cut
  
  
  
  1.11      +1 -62     parrot/dynclasses/pyobject.pmc
  
  Index: pyobject.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pyobject.pmc,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- pyobject.pmc      18 Dec 2004 03:51:47 -0000      1.10
  +++ pyobject.pmc      20 Dec 2004 13:10:18 -0000      1.11
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pyobject.pmc,v 1.10 2004/12/18 03:51:47 rubys Exp $
  +$Id: pyobject.pmc,v 1.11 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -762,67 +762,6 @@
   
   /*
   
  -=item C<PMC *find_method(STRING *method_name)>
  -
  -Looks up the method for C<*method_name> and returns it. If no method is
  -found then lookup an attribute by this name, and return it.  If all else
  -fails, return null.
  -
  -=cut
  -
  -TODO: create separate type objects for each builtin type which has
  -direct pointer to the global hash for this particular class.
  -
  -*/
  -
  -    PMC* find_method(STRING* method_name) {
  -        return Parrot_default_find_method(INTERP, SELF, method_name);
  -    }
  -
  -/*
  -
  -=item C<PMC* subclass(STRING *name)>
  -
  -Create a subclass of the builtin class.  In additon to creating a
  -new class (of type PyProxyType), an instance of PyProxyClass is also
  -created and defined as the base class for the new class.
  -
  -See the description of PyProxyType and PyProxyClass to see how
  -new instances are created and how methods are forwarded respectively.
  -
  -=cut
  -
  -TODO: create separate type objects for each builtin type and replace
  -this logic with a TypeError.
  -
  -*/
  -
  -    PMC* subclass(STRING* name) {
  -        INTVAL dynclass_PyProxyType, dynclass_PyProxyClass;
  -        PMC *proxy_type, *proxy_class, *nameprop;
  -        STRING *NAME, *BASES;
  -
  -        dynclass_PyProxyClass = Parrot_PMC_typenum(INTERP, "PyProxyClass");
  -        proxy_class = pmc_new(INTERP, dynclass_PyProxyClass);
  -
  -        BASES = const_string(INTERP, "__bases__");
  -        VTABLE_setprop(INTERP, proxy_class, BASES, SELF);
  -
  -        dynclass_PyProxyType = Parrot_PMC_typenum(INTERP, "PyProxyType");
  -        proxy_type = pmc_new(INTERP, dynclass_PyProxyType);
  -
  -        NAME  = const_string(INTERP, "__name__");
  -        nameprop = pmc_new(INTERP, dynclass_PyString);
  -        VTABLE_setprop(INTERP, proxy_type, NAME, nameprop);
  -        VTABLE_set_string_native(INTERP, nameprop, name);
  -
  -        VTABLE_setprop(INTERP, proxy_type, BASES, proxy_class);
  -
  -        return proxy_type;
  -    }
  -
  -/*
  -
   =back
   
   =cut
  
  
  
  1.5       +2 -2      parrot/dynclasses/pyproxyclass.pmc
  
  Index: pyproxyclass.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pyproxyclass.pmc,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- pyproxyclass.pmc  18 Dec 2004 03:51:47 -0000      1.4
  +++ pyproxyclass.pmc  20 Dec 2004 13:10:18 -0000      1.5
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pyproxyclass.pmc,v 1.4 2004/12/18 03:51:47 rubys Exp $
  +$Id: pyproxyclass.pmc,v 1.5 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -26,7 +26,7 @@
   static INTVAL dynclass_PyProxyClass;
   static STRING *PROXY;
   
  -pmclass PyProxyClass extends PyObject dynpmc group python_group {
  +pmclass PyProxyClass extends PyType dynpmc group python_group {
   
   /*
   
  
  
  
  1.5       +64 -26    parrot/dynclasses/pyproxytype.pmc
  
  Index: pyproxytype.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pyproxytype.pmc,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- pyproxytype.pmc   14 Dec 2004 13:37:47 -0000      1.4
  +++ pyproxytype.pmc   20 Dec 2004 13:10:18 -0000      1.5
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pyproxytype.pmc,v 1.4 2004/12/14 13:37:47 rubys Exp $
  +$Id: pyproxytype.pmc,v 1.5 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -65,13 +65,18 @@
   
   static INTVAL dynclass_PyClass;
   static INTVAL dynclass_PyString;
  +static INTVAL dynclass_PyProxyClass;
   static INTVAL dynclass_PyProxyType;
   static STRING *BASES;
   static STRING *CLASS;
   static STRING *INIT;
   static STRING *NAME;
  +static STRING *NEW;
   static STRING *PROXY;
   
  +struct parrot_regs_t *
  +Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub);
  +
   pmclass PyProxyType extends PyType dynpmc group python_group {
   
   /*
  @@ -87,6 +92,7 @@
   
       void class_init() {
           if (pass) {
  +            dynclass_PyProxyClass = Parrot_PMC_typenum(INTERP, 
"PyProxyClass");
               dynclass_PyProxyType = Parrot_PMC_typenum(INTERP, "PyProxyType");
               dynclass_PyClass = Parrot_PMC_typenum(INTERP, "PyClass");
               dynclass_PyString = Parrot_PMC_typenum(INTERP, "PyString");
  @@ -94,6 +100,7 @@
               CLASS = const_string(INTERP, "__class__");
               INIT  = const_string(INTERP, "__init__");
               NAME  = const_string(INTERP, "__name__");
  +            NEW   = const_string(INTERP, "__new__");
               PROXY = const_string(INTERP, "__proxy__");
           }
       }
  @@ -109,39 +116,55 @@
   
   =cut
   
  -TODO: reconcile this with Parrot's instantiate VTABLE entry.
  -
   */
   
       void* invoke(void *next) {
  -        PMC *proxy_class, *object_class, *proxy, *object, *init;
  +        PMC *object_class, *proxy, *object, *init, *new;
   
  -        proxy_class = VTABLE_getprop(INTERP, SELF, BASES);
  -        object_class = VTABLE_getprop(INTERP, proxy_class, BASES);
  -        while (1) {
  -            PMC *parent_class = VTABLE_getprop(INTERP, object_class, BASES);
  -            if (!parent_class || !VTABLE_defined(INTERP, parent_class))
  -                break;
  -            object_class = parent_class;
  +        object_class = VTABLE_getprop(INTERP, SELF, PROXY);
  +        if (!object_class || !VTABLE_defined(INTERP, object_class))
  +            object_class = SELF;
  +
  +        new = VTABLE_find_method(INTERP, SELF, NEW);
  +        init = VTABLE_find_method(INTERP, SELF, INIT);
  +        if (new || init) {
  +            int i = REG_INT(3)++;
  +            while (i--)
  +                REG_PMC(6+i)=REG_PMC(5+i);
           }
   
  -        object = pmc_new(INTERP, object_class->vtable->base_type);
  +        if (new) {
  +            struct parrot_regs_t *bp;
  +            struct Parrot_Context ctx;
  +            save_context(interpreter, &ctx);
  +            INTERP->ctx.current_object = SELF;
  +            REG_PMC(5) = SELF;
  +            bp = Parrot_PyClass_runops_fromc(INTERP, new);
  +            object = BP_REG_PMC(bp,5);
  +            restore_context(interpreter, &ctx);
  +        }
  +        else {
  +            object = pmc_new(INTERP, object_class->vtable->base_type);
  +        }
   
  -        proxy = pmc_new(interpreter, dynclass_PyClass);
  -        VTABLE_setprop(INTERP, proxy, CLASS, REG_PMC(0));
  +        if (object_class == SELF)
  +            proxy = object;
  +        else {
  +            proxy = pmc_new(interpreter, dynclass_PyClass);
  +            VTABLE_setprop(INTERP, proxy, CLASS, REG_PMC(0));
  +            VTABLE_setprop(INTERP, proxy, PROXY, object);
  +        }
   
  -        init = VTABLE_find_method(INTERP, proxy, INIT);
           if (init) {
  +            struct Parrot_Context ctx;
  +            save_context(interpreter, &ctx);
               INTERP->ctx.current_object = proxy;
  -            Parrot_runops_fromc(INTERP, init);
  -        }
  -        else {
  -            VTABLE_invoke(INTERP, object, next);
  -            object = REG_PMC(5);
  +            REG_PMC(5) = proxy;
  +            Parrot_PyClass_runops_fromc(INTERP, init);
  +            restore_context(interpreter, &ctx);
           }
   
  -        VTABLE_setprop(INTERP, proxy, PROXY, object);
  -
  +        REG_INT(3) = 1;
           REG_PMC(5) = proxy;
           return next;
       }
  @@ -159,12 +182,27 @@
   */
   
       PMC* subclass(STRING* name) {
  -        PMC *ret = pmc_new(INTERP, dynclass_PyProxyType);
  +        PMC *newclass = pmc_new(INTERP, dynclass_PyProxyType);
  +        PMC *proxy = VTABLE_getprop(INTERP, SELF, PROXY);
           PMC *nameprop = pmc_new(INTERP, dynclass_PyString);
  +
  +        if (proxy && VTABLE_defined(INTERP, proxy)) {
  +            /* proxy is already set up */
  +            VTABLE_setprop(INTERP, newclass, BASES, SELF);
  +            VTABLE_setprop(INTERP, newclass, PROXY, proxy);
  +        }
  +        else {
  +            /* need to create a proxy class */
  +            PMC *proxy_class = pmc_new(INTERP, dynclass_PyProxyClass);
  +            VTABLE_setprop(INTERP, proxy_class, BASES, SELF);
  +            VTABLE_setprop(INTERP, newclass, BASES, proxy_class);
  +            VTABLE_setprop(INTERP, newclass, PROXY, SELF);
  +        }
  +
           VTABLE_set_string_native(INTERP, nameprop, name);
  -        VTABLE_setprop(INTERP, ret, NAME, nameprop);
  -        VTABLE_setprop(INTERP, ret, BASES, SELF);
  -        return ret;
  +        VTABLE_setprop(INTERP, newclass, NAME, nameprop);
  +
  +        return newclass;
       }
   
   /*
  
  
  
  1.8       +56 -17    parrot/dynclasses/pytype.pmc
  
  Index: pytype.pmc
  ===================================================================
  RCS file: /cvs/public/parrot/dynclasses/pytype.pmc,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- pytype.pmc        18 Dec 2004 03:51:47 -0000      1.7
  +++ pytype.pmc        20 Dec 2004 13:10:18 -0000      1.8
  @@ -1,6 +1,6 @@
   /*
   Copyright: 2001-2003 The Perl Foundation.  All Rights Reserved.
  -$Id: pytype.pmc,v 1.7 2004/12/18 03:51:47 rubys Exp $
  +$Id: pytype.pmc,v 1.8 2004/12/20 13:10:18 rubys Exp $
   
   =head1 NAME
   
  @@ -25,11 +25,14 @@
   static INTVAL dynclass_PyClass;
   static INTVAL dynclass_PyString;
   static INTVAL dynclass_PyType;
  +static STRING *BASES;
   static STRING *CLASS;
   static STRING *INIT;
   static STRING *NAME;
  -static STRING *BASES;
  -static STRING *PYTYPE;
  +static STRING *NEW;
  +
  +struct parrot_regs_t *
  +Parrot_PyClass_runops_fromc(Parrot_Interp interpreter, PMC *sub);
   
   pmclass PyType dynpmc group python_group {
   
  @@ -49,16 +52,30 @@
               dynclass_PyClass = Parrot_PMC_typenum(INTERP, "PyClass");
               dynclass_PyString = Parrot_PMC_typenum(INTERP, "PyString");
               dynclass_PyType = Parrot_PMC_typenum(INTERP, "PyType");
  -            CLASS = const_string(INTERP, "__class__");
  -            INIT = const_string(INTERP, "__init__");
  -            NAME = const_string(INTERP, "__name__");
               BASES = const_string(INTERP, "__bases__");
  -            PYTYPE = const_string(INTERP, "PyType");
  +            CLASS = const_string(INTERP, "__class__");
  +            INIT  = const_string(INTERP, "__init__");
  +            NAME  = const_string(INTERP, "__name__");
  +            NEW   = const_string(INTERP, "__new__");
           }
       }
   
   /*
   
  +=item C<void add_method(STRING *method_name, PMC *sub)>
  +
  +Store the method as a property of this class.
  +
  +=cut
  +
  +*/
  +
  +    void add_method(STRING *method_name, PMC *sub_pmc) {
  +        VTABLE_setprop(INTERP, SELF, method_name, sub_pmc);
  +    }
  +
  +/*
  +
   =item C<PMC *find_method(STRING *method_name)>
   
   Looks up the method for C<*method_name> and returns it.
  @@ -74,7 +91,7 @@
           if (method && VTABLE_defined(INTERP, method)) return method;
   
           parent = VTABLE_getprop(INTERP, SELF, BASES);
  -        if (parent) {
  +        if (parent && VTABLE_defined(INTERP, parent)) {
               return VTABLE_find_method(INTERP, parent, method_name);
           }
   
  @@ -98,7 +115,7 @@
           if (attr && VTABLE_defined(INTERP, attr)) return attr;
   
           parent = VTABLE_getprop(INTERP, SELF, BASES);
  -        if (parent) {
  +        if (parent && VTABLE_defined(INTERP, parent)) {
               attr = VTABLE_get_attr_str(INTERP, parent, idx);
           }
   
  @@ -124,21 +141,43 @@
   */
   
       void* invoke(void* next) {
  -        PMC *object, *init;
  +        PMC *object, *init, *new;
  +
  +        new = VTABLE_find_method(INTERP, SELF, NEW);
  +        init = VTABLE_find_method(INTERP, SELF, INIT);
  +
  +        if (new || init) {
  +            int i = REG_INT(3)++;
  +            while (i--) 
  +                REG_PMC(6+i)=REG_PMC(5+i);
  +        }
  +
  +        if (new) {
  +            struct parrot_regs_t *bp;
  +            struct Parrot_Context ctx;
  +            save_context(interpreter, &ctx);
  +            INTERP->ctx.current_object = SELF;
  +            REG_PMC(5) = SELF;
  +            bp = Parrot_PyClass_runops_fromc(INTERP, new);
  +            object = BP_REG_PMC(bp,5);
  +            restore_context(interpreter, &ctx);
  +        }
  +        else {
  +            object = pmc_new(interpreter, dynclass_PyClass);
  +        }
   
  -        object = pmc_new(interpreter, dynclass_PyClass);
           VTABLE_setprop(INTERP, object, CLASS, REG_PMC(0));
   
  -        init = VTABLE_find_method(INTERP, object, INIT);
           if (init) {
  -            int i = REG_INT(3)++;
  -            for (i=REG_INT(3); i>0; i--)
  -               REG_PMC(5+i)=REG_PMC(4+i);
  -            REG_PMC(5) = object;
  +            struct Parrot_Context ctx;
  +            save_context(interpreter, &ctx);
               INTERP->ctx.current_object = object;
  -            Parrot_runops_fromc(INTERP, init);
  +            REG_PMC(5) = object;
  +            Parrot_PyClass_runops_fromc(INTERP, init);
  +            restore_context(interpreter, &ctx);
           }
   
  +        REG_INT(3) = 1;
           REG_PMC(5) = object;
           return next;
       }
  
  
  
  1.9       +1 -1      parrot/languages/python/README
  
  Index: README
  ===================================================================
  RCS file: /cvs/public/parrot/languages/python/README,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- README    18 Dec 2004 15:39:14 -0000      1.8
  +++ README    20 Dec 2004 13:10:20 -0000      1.9
  @@ -23,7 +23,7 @@
   
     b1: passes.
     b2: passes.
  -  b3: need to implement __new__
  +  b3: need to implement list.sort
     b4: there is no b4!
     b5: awaiting completion of float, complex, ...
     b6: requires a dictionary with integer keys.
  
  
  

Reply via email to