<commit_before>=head1 TITLE

Parrot::Coroutine - A pure PIR implementation of coroutines

=head1 VERSION

 $Id$

=head1 SYNOPSIS

    .sub __onload :load
        load_bytecode 'Parrot/Coroutine.pir'
    .end

    ## Recursive coroutine to enumerate tree elements.  Each element that is
    ## not a FixedPMCArray is yielded in turn.
    .sub enumerate_tree
        .param pmc coro
        .param pmc tree_node
        .param int depth :optional
        .param int depth_p :opt_flag

        if depth_p goto have_depth
        depth = 0
    have_depth:
        inc depth

        $I0 = isa tree_node, 'FixedPMCArray'
        if $I0 goto recur
        print "[leaf "
        print tree_node
        print "]\n"
        coro.'yield'(tree_node)
        .return ()

    recur:
        ## Loop through array elements, recurring on each.
        .local int size, i
        i = 0
        size = tree_node
    again:
        if i >= size goto done
        print "[recur: depth "
        print depth
        print ' elt '
        print i
        print "]\n"
        $P1 = tree_node[i]
        enumerate_tree(coro, $P1, depth)
        inc i
        goto again
    done:
        .return ()
    .end

    .sub print_tree
        .param pmc tree

        .local int coro_class, idx
        .local pmc coro
        .const .Sub coro_sub = "enumerate_tree"
        coro = new 'Parrot::Coroutine', coro_sub
        ($P0 :optional, $I0 :opt_flag) = coro.'resume'(coro, tree)
        idx = 0

    loop:
        unless $I0 goto done
        print 'print_tree:  '
        print idx
        print ' => '
        print $P0
        print "\n"
        ($P0 :optional, $I0 :opt_flag) = coro.'resume'()
        goto loop
    done:
    .end

=head1 DESCRIPTION

This object class provides an implementation of coroutines that is written
in pure PIR using continuations.

=cut

.sub __loadtime_create_class :load
    $P0 = get_class "Parrot::Coroutine"
    unless null $P0 goto END
    $P0 = newclass "Parrot::Coroutine"
    addattribute $P0, "state"       ## State:  1 is new/valid, 0 is dead.
    addattribute $P0, "initial_sub" ## Initial sub.
    addattribute $P0, "yield_cont"  ## Continuation to for yielding.
    addattribute $P0, "resume_cont" ## Continuation from which to resume.
END:
    .return ()
.end

.namespace ["Parrot::Coroutine"]

.include "interpinfo.pasm"

=head2 METHODS

=head3 B<__init_pmc(sub)>

This method is normally called via the C<new> op:

    .local pmc coro
    .const .Sub coro_sub = "enumerate_tree"
    coro_class = get_class 'Parrot::Coroutine'
    coro = coro_class.'new'('initial_sub' => coro_sub)

Given a sub, it initializes a new C<Parrot::Coroutine> object.
<commit_msg>   + Remove gratuitous "__" from names.<commit_after>=head1 TITLE

Parrot::Coroutine - A pure PIR implementation of coroutines

=head1 VERSION

 $Id$

=head1 SYNOPSIS

    .sub onload :load
        load_bytecode 'Parrot/Coroutine.pir'
    .end

    ## Recursive coroutine to enumerate tree elements.  Each element that is
    ## not a FixedPMCArray is yielded in turn.
    .sub enumerate_tree
        .param pmc coro
        .param pmc tree_node
        .param int depth :optional
        .param int depth_p :opt_flag

        if depth_p goto have_depth
        depth = 0
    have_depth:
        inc depth

        $I0 = isa tree_node, 'FixedPMCArray'
        if $I0 goto recur
        print "[leaf "
        print tree_node
        print "]\n"
        coro.'yield'(tree_node)
        .return ()

    recur:
        ## Loop through array elements, recurring on each.
        .local int size, i
        i = 0
        size = tree_node
    again:
        if i >= size goto done
        print "[recur: depth "
        print depth
        print ' elt '
        print i
        print "]\n"
        $P1 = tree_node[i]
        enumerate_tree(coro, $P1, depth)
        inc i
        goto again
    done:
        .return ()
    .end

    .sub print_tree
        .param pmc tree

        .local int coro_class, idx
        .local pmc coro
        .const .Sub coro_sub = "enumerate_tree"
        coro = new 'Parrot::Coroutine', coro_sub
        ($P0 :optional, $I0 :opt_flag) = coro.'resume'(coro, tree)
        idx = 0

    loop:
        unless $I0 goto done
        print 'print_tree:  '
        print idx
        print ' => '
        print $P0
        print "\n"
        ($P0 :optional, $I0 :opt_flag) = coro.'resume'()
        goto loop
    done:
    .end

=head1 DESCRIPTION

This object class provides an implementation of coroutines that is written
in pure PIR using continuations.

=cut

.sub onload_create_class :load
    $P0 = get_class "Parrot::Coroutine"
    unless null $P0 goto END
    $P0 = newclass "Parrot::Coroutine"
    addattribute $P0, "state"       ## State:  1 is new/valid, 0 is dead.
    addattribute $P0, "initial_sub" ## Initial sub.
    addattribute $P0, "yield_cont"  ## Continuation to for yielding.
    addattribute $P0, "resume_cont" ## Continuation from which to resume.
END:
    .return ()
.end

.namespace ["Parrot::Coroutine"]

.include "interpinfo.pasm"

=head2 METHODS

=head3 B<init_pmc(sub)>

This method is normally called via the C<new> op:

    .local pmc coro
    .const .Sub coro_sub = "enumerate_tree"
    coro_class = get_class 'Parrot::Coroutine'
    coro = coro_class.'new'('initial_sub' => coro_sub)

Given a sub, it initializes a new C<Parrot::Coroutine> object.

{'fraction_non_alphanumeric': 0.09357593761604159, 'fraction_numerical': 0.0103973264017824, 'mean_word_length': 2.113872832369942, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3509889', 'n_tokens_mistral': 1815, 'n_tokens_neox': 1785, 'n_words': 562}