Skip to content

Instantly share code, notes, and snippets.

Created June 26, 2011 22:09
Show Gist options
  • Save anonymous/1048049 to your computer and use it in GitHub Desktop.
Save anonymous/1048049 to your computer and use it in GitHub Desktop.
# This checks if we have something of the form * op *, * op <thing> or
# <thing> op * and if so, and if it's not one of the ops we do not
# auto-curry for, emits a closure instead. We hard-code the things not
# to curry for now; in the future, we will inspect the multi signatures
# of the op to decide, or likely store things in this hash from that
# introspection and keep it as a quick cache.
# %curried == 0 means do not curry
# %curried == 1 means curry WhateverCode only
# %curried == 2 means curry both WhateverCode and Whatever (default)
INIT {
%curried{'&infix:<...>'} := 0;
%curried{'&infix:<...^>'} := 0;
%curried{'&prefix:<^>'} := 0;
%curried{'&infix:<~~>'} := 0;
%curried{'&infix:<=>'} := 0;
%curried{'&infix:<:=>'} := 0;
%curried{'WHAT'} := 0;
%curried{'HOW'} := 0;
%curried{'WHO'} := 0;
%curried{'WHERE'} := 0;
%curried{'&infix:<..>'} := 1;
%curried{'&infix:<..^>'} := 1;
%curried{'&infix:<^..>'} := 1;
%curried{'&infix:<^..^>'} := 1;
%curried{'&infix:<xx>'} := 1;
}
sub whatever_curry($/, $past, $upto_arity) {
my $curried := $past.isa(PAST::Op)
&& ($past<pasttype> ne 'call' || pir::index($past.name, '&infix:') == 0)
&& %curried{$past.name};
my $i := 0;
my $whatevers := 0;
while $curried && $i < $upto_arity {
$whatevers += $past[$i].returns eq 'WhateverCode'
|| $curried > 1 && $past[$1].returns eq 'Whatever';
}
if $whatevers {
my $i = 0;
my @params;
while $i < $upto_arity {
my $old := $past[$i];
if $old.returns eq 'WhateverCode' {
my $new := PAST::Op.new( :pasttype<call>, :node($/), $old);
my $acount := 0;
while $acount < $old.arity {
my $pname := '$x' ~ (+@params);
@params.push(hash(
:variable_name($pname),
:nominal_type($*ST.find_symbol(['Mu'])),
:is_parcel(1),
));
## XXX need code to put var into scope
$new.push(PAST::Var.new(:name($pname), XXX));
}
$past[$i] := $new;
}
elsif $curried > 1 && $old.returns eq 'Whatever' {
my $pname := '$x' ~ (+@params);
@params.push(hash(
:variable_name($pname),
:nominal_type($*ST.find_symbol(['Mu'])),
:is_parcel(1),
));
my $new := PAST::Var.new(:name($pname), XXX);
$past[$i] := $new;
}
$i++;
}
my $block := XXX
my $signature := create_signature_object(@params, $block);
add_signature_binding_code($block, $signature);
...
$past := $block;
}
$past
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment