Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Refactor Op::SubDef to delay choosing lexical name
  • Loading branch information
sorear committed Mar 13, 2011
1 parent eec33bf commit a800dde
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 42 deletions.
8 changes: 8 additions & 0 deletions lib/Kernel.cs
Expand Up @@ -1616,6 +1616,14 @@ public class Kernel {
return n;
}

public static P6any MakeDispatcher(P6any proto, P6any[] cands) {
string s1 = "Dispatch";
foreach (P6any s in cands)
s1 += ", " + ((SubInfo)s.GetSlot("info")).name;
Console.WriteLine("MakeDispatcher: {0}", s1);
return AnyP;
}

public static bool SaferMode;

private static Frame SaferTrap(Frame th) {
Expand Down
34 changes: 13 additions & 21 deletions src/NieczaActions.pm6
Expand Up @@ -274,17 +274,14 @@ method quote:s ($/) { make $<pat>.ast }
method transparent($/, $op, :$once = False, :$ltm, :$class = 'Sub',
:$type = 'sub', :$sig = Sig.simple) {
::Op::SubDef.new(|node($/), var => self.gensym, :$once,
body => Body.new(
transparent => True,
::Op::SubDef.new(|node($/), :$once, body => Body.new(:transparent,
:$ltm, :$class, :$type, signature => $sig, do => $op));
}

method rxembed($/, $op, $trans) {
::Op::CallSub.new(|node($/),
positionals => [ ::Op::MakeCursor.new(|node($/)) ],
invocant => ::Op::SubDef.new(|node($/),
var => self.gensym,
once => True,
body => Body.new(
transparent => $trans,
Expand Down Expand Up @@ -430,9 +427,6 @@ method regex_def($/) {
return Nil;
}

my $var = ($scope eq 'anon' || $scope eq 'has') ?? self.gensym
!! '&' ~ $name;

my $ast = $<regex_block>.ast;
if $isproto {
$ast = ::RxOp::ProtoRedis.new(name => $name);
Expand All @@ -449,8 +443,8 @@ method regex_def($/) {
my @lift = $ast.oplift;
($ast, my $mb) = OptRxSimple.run($ast);
make ::Op::SubDef.new(|node($/),
var => $var,
method_too => ($scope eq 'has' ?? ['normal', $cname // $name] !! Any),
bindlex => ($scope ne 'anon' && $scope ne 'has'),
bindmethod => ($scope eq 'has' ?? ['normal', $cname // $name] !! Any),
body => Body.new(
ltm => $lad,
returnable => True,
Expand Down Expand Up @@ -2490,10 +2484,10 @@ method routine_declarator:sub ($/) { make $<routine_def>.ast }
method routine_declarator:method ($/) { make $<method_def>.ast }
method routine_declarator:submethod ($/) {
make $<method_def>.ast;
if $/.ast.method_too.[0] ne 'normal' {
if $/.ast.bindmethod.[0] ne 'normal' {
$/.CURSOR.sorry("Call pattern decorators cannot be used with submethod");
}
$/.ast.method_too.[0] = 'sub';
$/.ast.bindmethod.[0] = 'sub';
}

my $next_anon_id = 0;
Expand All @@ -2518,10 +2512,10 @@ method block_to_immediate($/, $type, $blk) {
positionals => []);
}

method block_to_closure($/, $body, :$outer_key, :$method_too, :$once,
:$exports) {
::Op::SubDef.new(|node($/), var => ($outer_key // self.gensym),
:$body, :$once, :$method_too, exports => ($exports // []));
method block_to_closure($/, $body, :$bindlex, :$bindmethod, :$once,
:$bindpackages = []) {
::Op::SubDef.new(|node($/), :$bindlex, :$bindmethod, :$body, :$once,
:$bindpackages);
}

method get_placeholder_sig($/) {
Expand Down Expand Up @@ -2595,13 +2589,13 @@ method routine_def ($/) {
}

make self.block_to_closure($/,
bindlex => ($scope eq 'my'),
self.sl_to_block('sub',
$<blockoid>.ast,
returnable => !$return_pass,
subname => $m, :$unsafe,
signature => $signature),
outer_key => (($scope eq 'my') ?? "\&$m" !! Any),
exports => @export);
bindpackages => @export);
}

method method_def ($/) {
Expand Down Expand Up @@ -2632,8 +2626,6 @@ method method_def ($/) {
return Nil;
}

my $sym = ($scope eq 'my') ?? ('&' ~ $name) !! self.gensym;

if ($scope eq 'augment' || $scope eq 'supersede' || $scope eq 'state') {
$/.CURSOR.sorry("Illogical scope $scope for method");
return Nil;
Expand Down Expand Up @@ -2661,8 +2653,8 @@ method method_def ($/) {
subname => $name, :$unsafe,
signature => $sig ?? $sig.for_method !! Any);

make self.block_to_closure($/, $bl, outer_key => $sym,
method_too => ($scope ne 'anon' ?? [ $type, $name ] !! Any));
make self.block_to_closure($/, $bl, bindlex => ($scope eq 'my'),
bindmethod => ($scope ne 'anon' ?? [ $type, $name ] !! Any));
}

method block($/) { make self.sl_to_block('', $<blockoid>.ast); }
Expand Down
23 changes: 13 additions & 10 deletions src/NieczaPassBegin.pm6
Expand Up @@ -286,34 +286,37 @@ augment class Op::Super { #OK exist
augment class Op::SubDef { #OK exist
method begin() {
my $prefix = '';
if defined $.method_too {
if defined $.bindmethod {
$prefix = $*unit.deref(@*opensubs[*-1].body_of).name ~ ".";
}
$.symbol = $.bindlex ?? ('&' ~ $.body.name) !!
::GLOBAL::NieczaActions.gensym;
$.bindpackages //= [];
my $body = $.body.begin(:$prefix,
once => ($.body.type // '') eq 'voidbare');
@*opensubs[*-1].add_my_sub($.var, $body);
@*opensubs[*-1].add_my_sub($.symbol, $body);
my $r = $body.xref;
if $.exports || defined $.method_too {
if $.bindpackages || defined $.bindmethod {
$body.strong_used = True;
}
@*opensubs[*-1].create_static_pad if $body.strong_used;

if defined $.method_too {
if defined $.bindmethod {
if @*opensubs[*-1].augment_hack {
if $.method_too[1] ~~ Op {
if $.bindmethod[1] ~~ Op {
die "Computed names are legal only in parametric roles";
}
push @*opensubs[*-1].augment_hack,
[ @$.method_too, $.var, $r ];
[ @$.bindmethod, $.symbol, $r ];
} else {
$*unit.deref(@*opensubs[*-1].body_of)\
.add_method(|$.method_too, $.var, $r);
.add_method(|$.bindmethod, $.symbol, $r);
}
}

@*opensubs[*-1].add_exports($*unit, $.var, $.exports);
$body.exports = [ map { [ @($body.cur_pkg), 'EXPORT', $_, $.var ] },
@$.exports ];
@*opensubs[*-1].add_exports($*unit, $.symbol, $.bindpackages);
$body.exports = [ map { [ @($body.cur_pkg), 'EXPORT', $_, $.symbol ] },
@$.bindpackages ];

$!body = Body;
}
Expand Down
4 changes: 2 additions & 2 deletions src/NieczaPassBeta.pm6
Expand Up @@ -23,7 +23,7 @@ sub run_optree($body, $op) {
return $op unless $op.^isa(::Op::CallSub) && no_named_params($op);
my $inv = $op.invocant;
return $op unless $inv.^isa(::Op::SubDef) && $inv.once;
my $cbody = $body.find_lex($inv.var) or return $op;
my $cbody = $body.find_lex($inv.symbol) or return $op;
$cbody = $cbody.body;
return $op unless is_removable_body($cbody);

Expand Down Expand Up @@ -78,7 +78,7 @@ sub beta_optimize($body, $op, $inv, $cbody) {
# the function
my @args = map { [ $_, ::GLOBAL::NieczaActions.gensym ] }, @( $op.positionals );

$body.delete_lex($inv.var);
$body.delete_lex($inv.symbol);
$*unit.xref.[$cbody.xref[1]] = Any;
{
my $c = $cbody.outer.zyg;
Expand Down
21 changes: 14 additions & 7 deletions src/Op.pm6
Expand Up @@ -643,23 +643,30 @@ class BareBlock is Op {

method statement_level() {
$.body.type = 'voidbare';
::Op::CallSub.new(invocant => ::Op::SubDef.new(var => $.var,
body => $.body, once => True));
::Op::CallSub.new(invocant => ::Op::SubDef.new(body => $.body, :once));
}
}

class SubDef is Op {
has $.var = die "SubDef.var required"; # Str
has $.body = die "SubDef.body required"; # Body
has $.method_too; # Array
has $.exports = []; # Array of Str

# often a gensym; will be set to the "correct" symbol if it is being
# used as a lexical; set by begin
has $.symbol; # Str, is rw

has $.multiness; # proto, only, multi, Any=null
has $.bindlex; # Bool
has $.bindpackages; # Array of Array of Str to install in
# used for 'our' and 'is export'
has $.bindmethod; # named array blocky thing

# Is candidate for beta-optimization. Not compatible with method_too,
# exports, ltm
has $.once = False; # is rw, Bool

method zyg() { ($.method_too && ($.method_too[1] ~~ Op)) ?? $.method_too[1] !! () }
method zyg() { ($.bindmethod && ($.bindmethod[1] ~~ Op)) ?? $.bindmethod[1] !! () }

method code($) { CgOp.scopedlex($.var) }
method code($) { CgOp.scopedlex($.symbol // 'Any') }
}

class Lexical is Op {
Expand Down
4 changes: 2 additions & 2 deletions src/Operator.pm6
Expand Up @@ -38,8 +38,8 @@ method wrap_in_function($/) {
my $i = -self.arity;
while $i++ { push @args, ::GLOBAL::NieczaActions.gensym }
my $do = self.with_args($/, map { mklex($/, $_) }, @args);
::Op::SubDef.new(|node($/), var => ::GLOBAL::NieczaActions.gensym,
body => Body.new( :transparent, signature => Sig.simple(@args), :$do));
::Op::SubDef.new(|node($/), body => Body.new(
:transparent, signature => Sig.simple(@args), :$do));
}

class Function is Operator {
Expand Down

0 comments on commit a800dde

Please sign in to comment.