develooper Front page | perl.perl6.internals | Postings from August 2002

[perl #16797] make subs closures

From:
Jonathan Sillito
Date:
August 27, 2002 14:12
Subject:
[perl #16797] make subs closures
Message ID:
rt-16797-35844.5.10724779199293@bugs6.perl.org
# New Ticket Created by  Jonathan Sillito 
# Please include the string:  [perl #16797]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=16797 >


This patch supersedes patch [perl #16087], which will not apply
correctly, since key stuff has changed.

I realize Dan has not given official word on how lexicals/closures are
to work yet (unless I missed it?), but I thought I would implement some
stuff anyway. I don't mind if I have to rework it when Dan gets to this
(probably not until sometime after the 0.0.8 release, I suppose?).

Anyway, this patch has two main goals. The first is to give scratchpads
a pointer to their parent pad. In the process I added a Scratchpad pmc
that uses its data pointer to point to a PerlHash (temporarily?) and
uses its cache pointer to point to its parent. I am not sure about this
use of the cache pointer, but it is only used internally so it should be
easy to change.

The scratchpad.pmc file is attached.

The second goal is to make subs closures. Below is an example of how
this works. You will notice that at the end of each sub there is an
extra 'pop_pad', this is to remove the pad that is pushed on the
pad_stack when the sub is invoked (or should the ret op take care of
this?).

    new_pad
    new P0, .Sub
    set_addr I3, get_closure
    set P0, I3
    invoke
   
    # move returned sub pmc to P0, then invoke twice
    set P0, P5
    # invoke puts correct scratch pad on top of stack
    invoke
    invoke

    find_lex P6, "a"
    print P6 # should be undef which prints as ''
    print "\n"
    pop_pad
    end

# a sub that returns a sub (closure)
get_closure:
    new_pad
    print "called get_closure\n"
    new P10, .PerlInt
    set P10, 57 
    store_lex "a", P10

    # sub grabs current current pad when created
    new P5, .Sub    
    set_addr I5, closure
    set P5, I5

    # returning sub pmc in first return pmc register,
    # which is P5
    set I5, 1
    pop_pad
    pop_pad # extra pad needs to be poped
    ret
closure:
    print "called closure\n"
    find_lex P2, "a"
    print P2
    print "\n"
    pop_pad # extra pad needs to be poped
    ret

produces the output:

    called get_closure
    called closure
    57
    called closure
    57


The attached file closure.patch has the following effects:

- changes lexical ops in core.ops to use Scratchpad pmc,
  and to use keys properly.
- adds Scratchpad to enum in include/parrot/pmc.h
- adds Parrot_Scratchpad_class_init(enum_class_Scratchpad); 
  to global_setup.c
- adds additional test to t/op/lexicals.t
- adds additional test to t/pmc/sub.t
- fixes examples/assembly/lexical.pasm (reverses PMC and 
  string arguments to store_lex op).
- changes new_sub method in sub.c
- changes invoke in sub.pmc (to put pad in place)

Comments?
--
Jonathan Sillito





-- attachment  1 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/35844/29037/feda4d/closure.patch

-- attachment  2 ------------------------------------------------------
url: http://rt.perl.org/rt2/attach/35844/29038/d0f8a9/scratchpad.pmc




nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About