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
  
  
  

Reply via email to