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.