Changeset 6376

Show
Ignore:
Timestamp:
08/20/05 15:47:35 (3 years ago)
Author:
iblech
svk:copy_cache_prev:
8581
Message:

* Usual svn props.
* PIL2JS: &?CALLER_CONTINUATION.

  • t/unspecced/cont.t: Added some type annotations and a new test. PIL2JS passes 14/14 with 6 unexpected succeedings. :)
  • PIL, PIL2JS.js: PIL2JS.cps2normal now works correctly with functions which reach the end of the program (this can happen, for example, with continuations :)). Previously, the program flow was restarted after the call to PIL2JS.cps2normal, resulting in certain regions running twice.
  • PIL, PIL::PVar, PIL::Subs: sub foo { {return}() } didn't compile, because PIL2JS only kept track of the current subtype, not of all subs it's currently in. Fixed.

* PIL2JS: PIL, PIL2JS.js, README: Context objects are now unboxed -- boxing was

never needed. Should give a small speedup.

Files:
1 added
15 modified

Legend:

Unmodified
Added
Removed
  • examples/hop6/LICENSE.txt

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • examples/hop6/Lexer.pm

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • examples/hop6/Parser.pm

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • examples/hop6/Stream.pm

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • examples/hop6/expr-parser.p6

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • examples/hop6/it2stream.p6

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • perl5/PIL2JS/README

    r6330 r6376  
    147147 
    148148Additionally to the arguments passed by the user, the first argument is always 
    149 a boxed C<PIL2JS.Context> object. Methods expect C<$?SELF> as their second 
     149an unboxed C<PIL2JS.Context> object. Methods expect C<$?SELF> as their second 
    150150argument. 
    151151 
  • perl5/PIL2JS/lib/PIL.pm

    r6315 r6376  
    1818# Are we in a sublike thing? If yes, what sublevel does that thing have? 
    1919our $IN_SUBLIKE = undef; 
     20our @IN_SUBLIKES; 
    2021 
    2122# What's the name of the sub we're currently in? 
     
    2324 
    2425# Our current pos? 
    25 our $CUR_POS  = bless [ "<unknown>", (0) x 4 ] => "PIL::MkPos"; 
     26our $CUR_POS  = bless { 
     27  posName => "<unknown>", 
     28  posBeginLine   => 0, 
     29  posBeginColumn => 0, 
     30  posEndLine     => 0, 
     31  posEndColumn   => 0, 
     32} => "PIL::MkPos"; 
    2633 
    2734# Are we in pilGlob? 
     
    181188    "\n// End of initialization of global vars and exportation of subs.\n"; 
    182189 
    183   return sprintf <<EOF, $decl_js, add_indent(2, join "\n", @glob_js, $init_js, $main_js); 
     190  return sprintf <<EOF, $decl_js, add_indent(3, join "\n", @glob_js, $init_js, $main_js); 
    184191%s 
    185192PIL2JS.catch_all_exceptions(function () { 
    186   PIL2JS.runloop(function () { 
    187     var PIL2JS = AlsoPIL2JS_SpeedupHack; 
    188     var pad = {}; PIL2JS_subpads.push(pad); 
    189     pad['\$?POSITION'] = _24main_3a_3a_3fPOSITION; 
    190     pad['\$_']         = _24main_3a_3a_; 
     193  PIL2JS.catch_end_exception(function() { 
     194    PIL2JS.runloop(function () { 
     195      var PIL2JS = AlsoPIL2JS_SpeedupHack; 
     196      var pad = {}; PIL2JS_subpads.push(pad); 
     197      pad['\$?POSITION'] = _24main_3a_3a_3fPOSITION; 
     198      pad['\$_']         = _24main_3a_3a_; 
    191199 
    192200%s 
     201    }); 
    193202  }); 
    194203}); 
     
    207216 
    208217  sub as_js { 
    209     return sprintf "new PIL2JS.Box.Constant(new PIL2JS.Context({ main: %s, type: %s }))", 
     218    return sprintf "new PIL2JS.Context({ main: %s, type: %s })", 
    210219      PIL::doublequote($_[0]->main), 
    211220      defined $_[0]->type 
  • perl5/PIL2JS/lib/PIL/PNil.pm

    r6270 r6376  
    1111 
    1212sub as_js { 
    13   return "" unless $PIL::IN_SUBLIKE; 
     13  # This is so even programs using function converted by PIL2JS.cps2normal can 
     14  # correctly terminate. 
     15  return "throw new PIL2JS.ControlException.end" unless $PIL::IN_SUBLIKE; 
    1416 
    1517  my $cxt   = "PIL2JS.Context.ItemAny"; 
  • perl5/PIL2JS/lib/PIL/PVar.pm

    r6276 r6376  
    77  die unless keys %{ $_[0] } == 1; 
    88  die if     ref(my $name = $_[0]->{pVarName}); 
     9  local $_; 
    910 
    1011  if($name eq "&return") { 
    1112    PIL::fail("Can't return outside a subroutine!") 
    12       unless $PIL::IN_SUBLIKE >= PIL::SUBROUTINE; 
     13      unless grep { $_ >= PIL::SUBROUTINE } @PIL::IN_SUBLIKES; 
     14    # XXX hack? 
     15    return bless { 
     16      pVarName => PIL::RawJS->new("PIL2JS.generic_return(subreturncc)") 
     17    } => "PIL::PVar"; 
     18  } elsif($name eq "&?CALLER_CONTINUATION") { 
     19    PIL::fail("There's no &?CALLER_CONTINUATION outside a subroutine!") 
     20      unless grep { $_ >= PIL::SUBROUTINE } @PIL::IN_SUBLIKES; 
    1321    # XXX hack? 
    1422    return bless { 
  • perl5/PIL2JS/lib/PIL/Subs.pm

    r6315 r6376  
    2323    $self->{pSubType} = bless [] => "PIL::$self->{pSubType}";  # minor hack 
    2424 
    25     local $PIL::IN_SUBLIKE = $self->{pSubType}->as_constant; 
     25    local $PIL::IN_SUBLIKE  = $self->{pSubType}->as_constant; 
     26    local @PIL::IN_SUBLIKES = (@PIL::IN_SUBLIKES, $self->{pSubType}->as_constant); 
    2627 
    2728    return bless { 
     
    4344 
    4445    local $PIL::IN_SUBLIKE  = $self->{pSubType}->as_constant; 
     46    local @PIL::IN_SUBLIKES = (@PIL::IN_SUBLIKES, $self->{pSubType}->as_constant); 
    4547    local $PIL::CUR_SUBNAME = $self->{pSubName}; 
    4648 
     
    132134    $self->{pType} = bless [] => "PIL::$self->{pType}";  # minor hack 
    133135 
    134     local $PIL::IN_SUBLIKE = $self->{pType}->as_constant; 
     136    local $PIL::IN_SUBLIKE  = $self->{pType}->as_constant; 
     137    local @PIL::IN_SUBLIKES = (@PIL::IN_SUBLIKES, $self->{pType}->as_constant); 
    135138 
    136139    # &PIL::Params::fixup returns the fixed PIL::Params and the fixed 
     
    155158 
    156159    local $PIL::IN_SUBLIKE  = $self->{pType}->as_constant; 
     160    local @PIL::IN_SUBLIKES = (@PIL::IN_SUBLIKES, $self->{pType}->as_constant); 
    157161    local $PIL::CUR_SUBNAME = "<anonymous@{[$PIL::CUR_SUBNAME ? ' in ' . $PIL::CUR_SUBNAME : '']}>"; 
    158162 
     
    201205    my $self = shift; 
    202206    local $PIL::IN_SUBLIKE  = PIL::SUBTHUNK; 
     207    local @PIL::IN_SUBLIKES = (@PIL::IN_SUBLIKES, PIL::SUBTHUNK); 
    203208    local $PIL::CUR_SUBNAME = "<thunk@{[$PIL::CUR_SUBNAME ? ' in ' . $PIL::CUR_SUBNAME : '']}>"; 
    204209 
  • perl5/PIL2JS/lib6/Prelude/JS.pm

    r6317 r6376  
    1515 
    1616use Prelude::JS::Code; 
     17use Prelude::JS::Continuations; 
    1718use Prelude::JS::ControlFlow; 
    1819use Prelude::JS::IO; 
  • perl5/PIL2JS/libjs/PIL2JS.js

    r6330 r6376  
    182182      (this.uid == undefined && other.uid == undefined && this.FETCH() == other.FETCH()) 
    183183    ) { 
    184       PIL2JS.die("Binding would create a bind cycle!"); 
     184      // PIL2JS.die("Binding would create a bind cycle!"); 
     185      // Bind cycles are actually legal. 
    185186    } 
    186187 
     
    659660PIL2JS.ControlException.redo.prototype.toString = 
    660661  function () { return "Can't \"redo\" outside a loop block!" }; 
     662PIL2JS.ControlException.end   = function () {}; 
    661663 
    662664// PIL2JS.generic_return -- generates a function, which, when invoked, will 
     
    784786}; 
    785787 
    786 PIL2JS.Context.Void      = new PIL2JS.Box.Constant(new PIL2JS.Context({ main: "void" })); 
    787 PIL2JS.Context.ItemAny   = new PIL2JS.Box.Constant(new PIL2JS.Context({ main: "item", type: "Any" })); 
    788 PIL2JS.Context.SlurpyAny = new PIL2JS.Box.Constant(new PIL2JS.Context({ main: "slurpy", type: "Any" })); 
     788PIL2JS.Context.Void      = new PIL2JS.Context({ main: "void" }); 
     789PIL2JS.Context.ItemAny   = new PIL2JS.Context({ main: "item", type: "Any" }); 
     790PIL2JS.Context.SlurpyAny = new PIL2JS.Context({ main: "slurpy", type: "Any" }); 
    789791 
    790792PIL2JS.print_exception = function (err) { 
     
    804806  try { code() } catch(err) { 
    805807    PIL2JS.print_exception(err); 
     808  } 
     809}; 
     810PIL2JS.catch_end_exception = function (code) { 
     811  try { code() } catch(err) { 
     812    if(err instanceof PIL2JS.ControlException.end) { 
     813      return; 
     814    } else { 
     815      throw err; 
     816    } 
    806817  } 
    807818}; 
  • perl5/Perl6-MetaModel/t/14_AUTOLOAD.t

    • Property svn:mime-type set to text/plain; charset=UTF-8
    • Property svn:eol-style set to native
  • t/unspecced/cont.t

    r4600 r6376  
    1010=cut 
    1111 
    12 plan 13; 
     12plan 14; 
    1313 
    1414sub simple1() returns Int { 
     
    1818is(simple1(), 2, 'using ec instead of return'); 
    1919 
    20 sub simple2($n) { 
     20sub simple2(Num $n) { 
    2121  if ($n == 5) { 
    2222    &?CALLER_CONTINUATION(1); 
     
    3535is(closure1(), 5, 'closure uses ec to escape', :todo); 
    3636 
    37 sub call_argument($f) { 
    38   return $f(); 
     37sub call_argument(Code $f, $arg) { 
     38  return $f($arg); 
    3939} 
    40 sub foo($f) returns Int { 
    41   call_argument($f); 
     40sub foo(Code $f) returns Int { 
     41  call_argument($f, 8); 
    4242  return 3; 
    4343} 
    44 sub passing1 returns Int { 
     44sub passing1 () returns Int { 
    4545  foo(&?CALLER_CONTINUATION); 
    4646  return 2; 
    4747} 
    48 eval_is('passing1()', 8, 'ec passed as an argument', :todo); 
     48is(try { passing1() }, 8, 'ec passed as an argument', :todo); 
    4949 
    50 sub is_five($n, $f) { 
     50sub is_five(Num $n, Code $f) { 
    5151  if ($n == 5) { 
    5252    $f(1); 
     
    5454  return 0; 
    5555} 
    56 sub passing2_not_cont($n) { 
     56sub passing2_not_cont(Num $n) { 
    5757  my $a = 9; 
    5858  is_five($n, sub { $a = 1 }); 
    5959  return $a; 
    6060} 
    61 sub passing2($n) { 
     61sub passing2(Num $n) { 
    6262  is_five($n, &?CALLER_CONTINUATION); 
    6363  return 9; 
    6464} 
    65 sub passing2_closure($n) { 
     65sub passing2_closure(Num $n) { 
    6666  my $c = &?CALLER_CONTINUATION; 
    6767  is_five($n, sub { $c(1) }); 
    6868  return 9; 
    6969} 
    70 is(passing2_not_cont(5), 1, 'is_five w/o ec'); 
    71 is(passing2_not_cont(2), 9, 'is_five w/o ec'); 
    72 is(passing2(5), 1, 'is_five passing ec itself', :todo); 
    73 is(passing2(2), 9, 'is_five passing ec itself'); 
    74 is(passing2_closure(5), 1, 'is_five passing ec via closure', :todo); 
    75 is(passing2_closure(2), 9, 'is_five passing ec via closure'); 
     70is(passing2_not_cont(5), 1, 'is_five w/o ec (1)'); 
     71is(passing2_not_cont(2), 9, 'is_five w/o ec (2)'); 
     72is(passing2(5), 1, 'is_five passing ec itself (1)', :todo); 
     73is(passing2(2), 9, 'is_five passing ec itself (2)'); 
     74is(passing2_closure(5), 1, 'is_five passing ec via closure (1)', :todo); 
     75is(passing2_closure(2), 9, 'is_five passing ec via closure (2)'); 
    7676 
    7777sub callconty() { 
     
    7979    return 1; 
    8080} 
    81 sub conty($c) { 
     81sub conty(Code $c) { 
    8282    $c(2); 
     83    return 3; 
    8384} 
    8485is(callconty(), 2, 'continuation bug', :todo<bug>); 
     
    8687# Now test complicated full continuations got from the same place. 
    8788 
    88 sub callcc (Code &block) {  &block(&?CALLER_CONTINUATION) } 
     89{ 
     90  sub callcc (Code &block) {  &block(&?CALLER_CONTINUATION) } 
    8991 
    90 my $cnt; 
    91 my $counter = 0; 
     92  my $cont; 
     93  my $counter = 0; 
    9294 
    93 callcc -> $cc { $cnt = $cc }; 
    94 $counter++; 
    95 ok 1, "$counter times through the loop"; 
    96 $cnt(undef) unless $counter == 3; 
    97 is($counter, 3, "Looping with a full continuation", :todo<feature>); 
     95  callcc -> $cc { $cont = $cc }; 
     96  $counter++; 
     97  $cont(undef) unless $counter == 3; 
     98  is($counter, 3, "Looping with a full continuation", :todo<feature>); 
     99} 
     100 
     101# Really evil: Store continuations in an aggregate 
     102{ 
     103  my %conts; 
     104  my $foo = sub { %conts<foo> = &?CALLER_CONTINUATION; return "normalfoo" }; 
     105  my $bar = sub { %conts<bar> = &?CALLER_CONTINUATION; return "normalbar" }; 
     106 
     107  my $history; 
     108  my $counter = 0; 
     109 
     110  $history ~= $foo(); $history ~= "foo$counter"; $counter++; 
     111  $history ~= $bar(); $history ~= "bar$counter"; $counter++; 
     112  %conts<foo>("secondfoo") if $counter <= 2; 
     113  %conts<bar>("secondbar") if $counter <= 4; 
     114 
     115  is 
     116    $history, 
     117    "normalfoofoo0normalbarbar1secondfoofoo2normalbarbar3secondbarbar4", 
     118    "continuations stored in an aggregate with loops"; 
     119}