cvsuser 04/12/06 10:09:37
Modified: dynclasses pyboolean.pmc pybuiltin.pmc pygen.pmc pytuple.pmc
languages/python/t/basic iter.t
t/pmc perlhash.t
Log:
Iterator support
Revision Changes Path
1.4 +36 -1 parrot/dynclasses/pyboolean.pmc
Index: pyboolean.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pyboolean.pmc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- pyboolean.pmc 30 Nov 2004 15:59:00 -0000 1.3
+++ pyboolean.pmc 6 Dec 2004 18:09:31 -0000 1.4
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pyboolean.pmc,v 1.3 2004/11/30 15:59:00 rubys Exp $
+$Id: pyboolean.pmc,v 1.4 2004/12/06 18:09:31 rubys Exp $
=head1 NAME
@@ -87,6 +87,41 @@
/*
+=item C<void set_integer_same(PMC *value)>
+
+Sets the value of the integer to the value of the C<PyInt> C<*value>.
+
+=cut
+
+*/
+
+ void set_integer_same (PMC * value) {
+ PMC_int_val(SELF) = PMC_int_val(value);
+ }
+
+/*
+
+=item C<void set_pmc(PMC *value)>
+
+Sets the PMC C<*value>, calling the appropriate C<set_*> method
+according to the type of C<*value>.
+
+=cut
+
+*/
+
+ void set_pmc (PMC* value) {
+ if (SELF->vtable->base_type == value->vtable->base_type) {
+ DYNSELF.set_integer_same(value);
+ }
+ else {
+ DYNSELF.morph(value->vtable->base_type);
+ DYNSELF.set_pmc(value);
+ }
+ }
+
+/*
+
=back
=cut
1.12 +25 -10 parrot/dynclasses/pybuiltin.pmc
Index: pybuiltin.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pybuiltin.pmc,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- pybuiltin.pmc 5 Dec 2004 01:31:18 -0000 1.11
+++ pybuiltin.pmc 6 Dec 2004 18:09:31 -0000 1.12
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pybuiltin.pmc,v 1.11 2004/12/05 01:31:18 rubys Exp $
+$Id: pybuiltin.pmc,v 1.12 2004/12/06 18:09:31 rubys Exp $
=head1 NAME
@@ -336,7 +336,16 @@
/* run filter func -
* TODO save registers once around loop
*/
- PMC *t = Parrot_runops_fromc_args(INTERP, func, "PP", item);
+ PMC *t;
+ if (func->vtable->base_type == enum_class_NCI) {
+ REG_PMC(5) = item;
+ REG_INT(3) = 1;
+ Parrot_runops_fromc(INTERP, func);
+ t = REG_PMC(5);
+ }
+ else {
+ t = Parrot_runops_fromc_args(INTERP, func, "PP", item);
+ }
if (!VTABLE_get_bool(INTERP, t))
continue;
}
@@ -593,22 +602,19 @@
while (VTABLE_get_bool(INTERP, iter)) {
PMC *item = VTABLE_shift_pmc(INTERP, iter);
if (!none_func) {
- /* run filter func -
- * TODO save registers once around loop
- */
- if (func->vtable->data == func) {
+ if (func->vtable->base_type == enum_class_NCI) {
REG_PMC(5) = item;
REG_INT(3) = 1;
- VTABLE_invoke(INTERP, func, 0);
+ Parrot_runops_fromc(INTERP, func);
item = REG_PMC(5);
- /* an object constructor */
}
else {
- item = Parrot_runops_fromc_args(INTERP, func, "PP", item);
+ item = Parrot_runops_fromc_args(INTERP, func, "PP",
item);
}
}
VTABLE_set_pmc_keyed_int(INTERP, res, i++, item);
}
+
return res;
}
@@ -780,7 +786,16 @@
/* run filter func -
* TODO save registers once around loop
*/
- res = Parrot_runops_fromc_args(INTERP, func, "PPP", res, item);
+ if (func->vtable->base_type == enum_class_NCI) {
+ REG_PMC(5) = res;
+ REG_PMC(6) = item;
+ REG_INT(3) = 2;
+ Parrot_runops_fromc(INTERP, func);
+ res = REG_PMC(5);
+ }
+ else {
+ res = Parrot_runops_fromc_args(INTERP, func, "PPP", res,
item);
+ }
}
if ((REG_INT(3)>2) && 0==VTABLE_elements(INTERP, res))
1.2 +151 -4 parrot/dynclasses/pygen.pmc
Index: pygen.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pygen.pmc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- pygen.pmc 10 Nov 2004 01:23:21 -0000 1.1
+++ pygen.pmc 6 Dec 2004 18:09:31 -0000 1.2
@@ -1,14 +1,14 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pygen.pmc,v 1.1 2004/11/10 01:23:21 rubys Exp $
+$Id: pygen.pmc,v 1.2 2004/12/06 18:09:31 rubys Exp $
=head1 NAME
-classes/pymodule.pmc - Python Module
+classes/pygen.pmc - Python Generator
=head1 DESCRIPTION
-These are the vtable functions for the Python Module base class
+These are the vtable functions for the Python Generator class
=head2 Methods
@@ -20,10 +20,63 @@
#include "parrot/parrot.h"
+static STRING *NEXT;
+static STRING *STOPITERATION;
+
pmclass PyGen dynpmc group python_group {
/*
+=item C<void class_init()>
+
+Class initialization.
+
+=cut
+
+*/
+
+ void class_init() {
+ if (pass) {
+ NEXT = const_string(INTERP, "next");
+ STOPITERATION = const_string(INTERP, "StopIteration");
+ }
+ }
+
+/*
+
+=item C<void init()>
+
+Initializes the key.
+
+=cut
+
+*/
+
+ void init () {
+ PObj_custom_mark_SET(SELF);
+ PMC_struct_val(SELF) = NULL;
+ PMC_pmc_val(SELF) = NULL;
+ }
+
+/*
+
+=item C<void mark()>
+
+Marks the hash as live.
+
+=cut
+
+*/
+
+ void mark () {
+ if (PMC_struct_val(SELF)) /* next value */
+ pobject_lives(INTERP, (PObj *) PMC_struct_val(SELF));
+ if (PMC_pmc_val(SELF)) /* next function */
+ pobject_lives(INTERP, (PObj *) PMC_pmc_val(SELF));
+ }
+
+/*
+
=item C<PMC *find_method(STRING *method_name)>
Looks up the method for C<*method_name> and returns it. If no method is
@@ -35,13 +88,107 @@
*/
PMC* find_method(STRING* method_name) {
- PMC * method = SUPER(method_name);
+ PMC *method;
+
+ if (0 == string_compare(INTERP, method_name, NEXT))
+ return PMC_pmc_val(SELF);
+
+ method = SUPER(method_name);
if (!method) method = VTABLE_getprop(INTERP, SELF, method_name);
return method;
}
/*
+=item C<INTVAL get_bool()>
+
+Returns true if there are more elements to return
+
+=cut
+
+*/
+
+ INTVAL get_bool () {
+ /* Do I already know what the next iteration will return? */
+ if (PMC_struct_val(SELF)) return 1;
+
+ /* Peek ahead */
+ new_internal_exception(INTERP);
+ push_new_c_exception_handler(INTERP, INTERP->exceptions);
+ if (!setjmp(INTERP->exceptions->destination)) {
+ PMC_struct_val(SELF) =
+ Parrot_runops_fromc_args(INTERP, PMC_pmc_val(SELF), "P");
+ pop_exception(INTERP);
+ } else {
+ /* TODO: check for something better than the message */
+ PMC *exception = REG_PMC(5);
+ STRING *message = VTABLE_get_string_keyed_int(INTERP, exception,
0);
+ if (0 != string_compare(INTERP, message, STOPITERATION)) {
+ rethrow_exception(INTERP, REG_PMC(5));
+ }
+ }
+
+ if (PMC_struct_val(SELF)) return 1;
+ return 0;
+ }
+
+/*
+
+=item C<PMC* get_iter ()>
+
+Return a new iterator for generator.
+
+=cut
+
+For now, return self. TODO: revisit this.
+
+*/
+
+ PMC* get_iter () {
+ return SELF;
+ }
+
+/*
+
+=item C<void set_pmc(PMC *value)>
+
+Sets the value of the NEXT function.
+
+=cut
+
+*/
+
+ void set_pmc (PMC* value) {
+ PMC_pmc_val(SELF) = value;
+ }
+
+/*
+
+=item C<PMC* shift_pmc()>
+
+Returns the next yielded element.
+
+=cut
+
+*/
+
+ PMC* shift_pmc () {
+ PMC *ret;
+
+ if (PMC_struct_val(SELF)) {
+ ret = PMC_struct_val(SELF);
+ PMC_struct_val(SELF) = NULL;
+ }
+ else {
+ ret = Parrot_runops_fromc_args(INTERP, PMC_pmc_val(SELF), "P");
+ }
+
+ return ret;
+ }
+
+
+/*
+
=back
=cut
1.4 +20 -1 parrot/dynclasses/pytuple.pmc
Index: pytuple.pmc
===================================================================
RCS file: /cvs/public/parrot/dynclasses/pytuple.pmc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- pytuple.pmc 2 Dec 2004 21:25:00 -0000 1.3
+++ pytuple.pmc 6 Dec 2004 18:09:31 -0000 1.4
@@ -1,6 +1,6 @@
/*
Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-$Id: pytuple.pmc,v 1.3 2004/12/02 21:25:00 rubys Exp $
+$Id: pytuple.pmc,v 1.4 2004/12/06 18:09:31 rubys Exp $
=head1 NAME
@@ -24,6 +24,7 @@
/* cache of classes referenced */
static INTVAL dynclass_PyInt;
+static INTVAL dynclass_PyFloat;
pmclass PyTuple extends PyObject need_ext does array dynpmc group
python_group {
@@ -41,6 +42,7 @@
void class_init() {
if (pass) {
dynclass_PyInt = Parrot_PMC_typenum(INTERP, "PyInt");
+ dynclass_PyFloat = Parrot_PMC_typenum(INTERP, "PyFloat");
}
}
@@ -101,6 +103,7 @@
*/
INTVAL elements () {
+ if (PMC_int_val(SELF) < 0) PMC_int_val(SELF) = 0;
return PMC_int_val(SELF);
}
@@ -251,6 +254,22 @@
/*
+=item C<void set_number_keyed(PMC *key, INTVAL value)>
+
+Sets the number value of the element at index C<key> to C<value>.
+
+=cut
+
+*/
+
+ void set_number_keyed (PMC *key, FLOATVAL value) {
+ PMC *val = pmc_new(INTERP, dynclass_PyFloat);
+ VTABLE_set_number_native(INTERP, val, value);
+ DYNSELF.set_pmc_keyed_int(PMC_int_val(key), val);
+ }
+
+/*
+
=item C<void set_pmc_keyed_int(INTVAL key, PMC *src)>
Sets the PMC value of the element at index C<key> to C<*src>.
1.6 +21 -21 parrot/languages/python/t/basic/iter.t
Index: iter.t
===================================================================
RCS file: /cvs/public/parrot/languages/python/t/basic/iter.t,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- iter.t 19 Jul 2004 15:57:06 -0000 1.5
+++ iter.t 6 Dec 2004 18:09:33 -0000 1.6
@@ -1,4 +1,4 @@
-# $Id: iter.t,v 1.5 2004/07/19 15:57:06 leo Exp $
+# $Id: iter.t,v 1.6 2004/12/06 18:09:33 rubys Exp $
use strict;
use lib '../../lib';
@@ -12,30 +12,30 @@
test(<<'CODE', 'iter string');
if __name__ == '__main__':
for i in "abc":
- print i
+ print i
CODE
test(<<'CODE', 'iter tuple');
if __name__ == '__main__':
for i in (1,2,3):
- print i
+ print i
CODE
test(<<'CODE', 'iter map');
if __name__ == '__main__':
for i in {"a":1,"b":2,"c":3}:
- if i == 'a' or i == 'b' or i == 'c':
- print "ok"
+ if i == 'a' or i == 'b' or i == 'c':
+ print "ok"
CODE
test(<<'CODE', 'generator');
def foo():
i=0
while (1):
- if i > 5:
- return
- yield "abcdefghi"[i]
- i = i + 1
+ if i > 5:
+ return
+ yield "abcdefghi"[i]
+ i = i + 1
def main():
i = foo()
@@ -44,27 +44,27 @@
print
if __name__ == "__main__":
- main()
+ main()
CODE
test(<<'CODE', 'generator - repeat');
def foo():
i=0
while (1):
- if i > 5:
- return
- yield "abcdefghi"[i]
- i = i + 1
+ if i > 5:
+ return
+ yield "abcdefghi"[i]
+ i = i + 1
def main():
for k in range(2):
- i = foo()
- for y in i:
- print y,
- print
+ i = foo()
+ for y in i:
+ print y,
+ print
if __name__ == "__main__":
- main()
+ main()
CODE
test(<<'CODE', 'enumerate, it.next');
@@ -88,9 +88,9 @@
print it.next()
print it.next()
try:
- print it.next()
+ print it.next()
except StopIteration:
- pass
+ pass
print "Ok"
CODE
1.51 +10 -3 parrot/t/pmc/perlhash.t
Index: perlhash.t
===================================================================
RCS file: /cvs/public/parrot/t/pmc/perlhash.t,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- perlhash.t 4 Dec 2004 19:23:44 -0000 1.50
+++ perlhash.t 6 Dec 2004 18:09:37 -0000 1.51
@@ -1,7 +1,7 @@
#! perl
# Copyright: 2001-2003 The Perl Foundation. All Rights Reserved.
-# $Id: perlhash.t,v 1.50 2004/12/04 19:23:44 rubys Exp $
+# $Id: perlhash.t,v 1.51 2004/12/06 18:09:37 rubys Exp $
=head1 NAME
@@ -1221,12 +1221,19 @@
new P0, .PerlHash
set P0['a'], 'x'
iter P1, P0
+ if P1 goto ok1
+ print "Not empty?\n"
shift P2, P1
print P2
print "\n"
- unless P1 goto ok
+ok1:
+ iter P1, P0
+ shift P2, P1
+ print P2
+ print "\n"
+ unless P1 goto ok2
print "Surprise!\n"
-ok:
+ok2:
end
.end
CODE