Author: jonathan
Date: Wed Aug 20 08:44:51 2008
New Revision: 30381

Added:
   branches/lazyrakudo/languages/perl6/src/classes/Iterator.pir   (contents, 
props changed)
Modified:
   branches/lazyrakudo/MANIFEST

Log:
[rakudo] Add new Iterator.pir (lazy list iterator), which I forgot to add in 
the last ci.

Modified: branches/lazyrakudo/MANIFEST
==============================================================================
--- branches/lazyrakudo/MANIFEST        (original)
+++ branches/lazyrakudo/MANIFEST        Wed Aug 20 08:44:51 2008
@@ -1938,6 +1938,7 @@
 languages/perl6/src/classes/Hash.pir                        [perl6]
 languages/perl6/src/classes/IO.pir                          [perl6]
 languages/perl6/src/classes/Int.pir                         [perl6]
+languages/perl6/src/classes/Iterator.pir                    [perl6]
 languages/perl6/src/classes/Junction.pir                    [perl6]
 languages/perl6/src/classes/List.pir                        [perl6]
 languages/perl6/src/classes/Mapping.pir                     [perl6]

Added: branches/lazyrakudo/languages/perl6/src/classes/Iterator.pir
==============================================================================
--- (empty file)
+++ branches/lazyrakudo/languages/perl6/src/classes/Iterator.pir        Wed Aug 
20 08:44:51 2008
@@ -0,0 +1,117 @@
+## $Id$
+
+=head1 NAME
+
+src/classes/Iterator.pir - Perl 6 Iterator class
+
+XXX Needs cleanup and probably fixes/changes before moving to trunk.
+
+=head2 Object Methods
+
+=over 4
+
+=cut
+
+.sub 'onload' :anon :load :init
+    .local pmc p6meta
+    p6meta = get_hll_global ['Perl6Object'], '$!P6META'
+    p6meta.'new_class'('Perl6Iterator', 'name'=>'Iterator', 'parent'=>'Any', 
'attributes'=>'@!list $!position')
+.end
+
+
+.sub 'get_bool' :vtable
+    .local pmc list, evaluated, unevaluated
+    .local int elems
+
+    # Check evaluated part.
+    list = getattribute self, "@!list"
+    evaluated = getattribute list, "@!evaluated"
+    elems = elements evaluated
+    if elems goto true
+
+    # Check unevaluated part; if we just have iterators, we need to make sure
+    # they have values (that is, if we have a list of ten exhausted iterators,
+    # we want to be sure that we return a false value here, since there are no
+    # more values to be obtained).
+    unevaluated = getattribute list, "@!unevaluated"
+    elems = elements unevaluated
+    unless elems goto false
+    .local int cur_check
+    cur_check = 0
+  try_loop:
+    $P0 = unevaluated[cur_check]
+    $I0 = isa $P0, 'Perl6Iterator'
+    unless $I0 goto true
+    if $P0 goto true
+    inc cur_check
+    if cur_check >= elems goto false
+    goto try_loop
+
+  true:
+    .return (1)
+  false:
+    .return (0)
+.end
+
+
+.sub 'shift_pmc' :vtable
+    .local pmc position, value, list
+    .local int elems_available
+
+    position = getattribute self, "$!position"
+    list = getattribute self, "@!list"
+    if position < 0 goto use_unevaluated
+
+    # If we're here, we're getting from the evaluated part - or at least,
+    # trying to.
+    .local pmc evaluated
+    evaluated = getattribute list, "@!evaluated"
+    elems_available = elements evaluated
+    $I0 = position
+    if elems_available <= $I0 goto out_of_evaluated
+
+    # We have things available in the evaluated portion. Get a value, then
+    # increment our position, and we're done.
+    value = evaluated[position]
+    inc position
+    .return (value)
+
+    # Here we find we have depleted our supply of evaluated values. Set the
+    # position to -1 to indicate this and fall through to using the unevaluated
+    # part of the list to service this request.
+  out_of_evaluated:
+    position = -1
+
+    # Here we take values from the unevaluated part of the list.
+  use_unevaluated:
+    .local pmc unevaluated, try
+    unevaluated = getattribute list, "@!unevaluated"
+  try_loop:
+    elems_available = elements unevaluated
+    if elems_available == 0 goto failure
+
+    # See if it's an iterator at the head of the list or not.
+    try = unevaluated[0]
+    $I0 = isa try, 'Perl6Iterator'
+    if $I0 goto get_from_iter
+    
+    # Not an iterator, so just pull this value off the head of the unevaluated
+    # part and hand it back.
+    value = unshift unevaluated
+    .return (value)
+
+    # We have an iterator. Make sure it's not exhausted, and if not get a value
+    # from it. If it is, then we need to remove it and try the next iterator.
+  get_from_iter:
+    unless try goto empty_iter
+    value = shift try
+    .return (value)
+  empty_iter:
+    $P0 = unshift unevaluated
+    goto try_loop
+
+    # If there's no elements available, we fail.
+  failure:
+    value = new 'Undef'
+    .return (value)
+.end

Reply via email to