From f4addf6d170223bfcc86fc0622a329a7173ab3ab Mon Sep 17 00:00:00 2001 From: Stefan O'Rear Date: Tue, 20 Jul 2010 23:19:19 -0700 Subject: [PATCH] Upward type inference for let --- CgOp.pm | 14 +++++++------- CodeGen.pm | 6 +++--- Decl.pm | 2 +- Op.pm | 5 ++--- Sig.pm | 3 +-- Unit.pm | 2 +- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/CgOp.pm b/CgOp.pm index 40f85372..4d90c859 100644 --- a/CgOp.pm +++ b/CgOp.pm @@ -249,7 +249,7 @@ use warnings; sub methodcall { my ($obj, $name, @args) = @_; - let($obj, 'Variable', sub { + let($obj, sub { CgOp::Primitive->new(op => [ 'call_method', 1, $name, scalar @args ], zyg => [ fetch($_[0]), $_[0], @args ])}); } @@ -272,7 +272,7 @@ use warnings; } else { my $n = shift; my $t = shift; - letn($n, $t, null($t), withtypes(@_)); + letn($n, null($t), withtypes(@_)); } } @@ -337,9 +337,9 @@ use warnings; } sub letn { - my ($name, $type, $value, @stuff) = @_; + my ($name, $value, @stuff) = @_; prog( - CgOp::Primitive->new(op => [ 'push_let', $name, $type ], + CgOp::Primitive->new(op => [ 'push_let', $name ], zyg => [ $value ]), @stuff, sink(CgOp::Primitive->new(op => [ 'pop_let', $name ]))); @@ -362,9 +362,9 @@ use warnings; my $nextlet = 0; sub let { - my ($head, $type, $bodyf) = @_; + my ($head, $bodyf) = @_; my $v = ($nextlet++); - letn($v, $type, $head, $bodyf->(letvar($v))); + letn($v, $head, $bodyf->(letvar($v))); } } @@ -408,7 +408,7 @@ use warnings; if (_okdelay($op->zyg->[scalar @sofar])) { $_recurse->(@sofar, $op->zyg->[scalar @sofar]); } else { - let($op->zyg->[scalar @sofar], 'XXX', + let($op->zyg->[scalar @sofar], sub { $_recurse->(@sofar, $_[0]) }); } }; diff --git a/CodeGen.pm b/CodeGen.pm index e231343a..09357c15 100644 --- a/CodeGen.pm +++ b/CodeGen.pm @@ -208,9 +208,9 @@ use 5.010; } sub push_let { - my ($self, $which, $ty) = @_; + my ($self, $which) = @_; my $var = "let!${which}!" . ($self->letdepths->{$which}++); - $self->lex2type->{$var} = $ty; + $self->lex2type->{$var} = $self->stacktype->[-1]; $self->rawlexput($var); } @@ -558,7 +558,7 @@ use 5.010; my ($self, $body) = @_; $self->peek_let('protopad'); $self->clr_new('Frame', 1); - $self->push_let('protopad', 'Frame'); + $self->push_let('protopad'); push @{ $self->bodies }, $body; } diff --git a/Decl.pm b/Decl.pm index 9a590b9d..ac27dd32 100644 --- a/Decl.pm +++ b/Decl.pm @@ -221,7 +221,7 @@ use CgOp; $self->body->outer($body); - CgOp::letn("how", "Variable", + CgOp::letn("how", CgOp::methodcall(CgOp::scopedlex("ClassHOW"), "new", CgOp::wrap(CgOp::clr_string($self->name // 'ANON'))), diff --git a/Op.pm b/Op.pm index 30fdacd9..9d2b1c7a 100644 --- a/Op.pm +++ b/Op.pm @@ -141,7 +141,7 @@ use CgOp; sub code { my ($self, $body) = @_; - CgOp::let($self->receiver->code($body), 'Variable', sub { + CgOp::let($self->receiver->code($body), sub { CgOp::methodcall(CgOp::newscalar(CgOp::how(CgOp::fetch($_[0]))), $self->name, $_[0], map { $_->code($body) } @{ $self->positionals })}); @@ -243,8 +243,7 @@ use CgOp; my $acc = (shift @r)->code($body); for (@r) { - $acc = CgOp::let($_->code($body), 'Variable', - sub { $self->red2($_[0], $acc) }); + $acc = CgOp::let($_->code($body), sub { $self->red2($_[0], $acc) }); } $acc; diff --git a/Sig.pm b/Sig.pm index 31a11018..7f48497d 100644 --- a/Sig.pm +++ b/Sig.pm @@ -42,8 +42,7 @@ use 5.010; if ($self->slurpy) { $self->target->binder( CgOp::let(CgOp::rawnew('DynObject', CgOp::getfield('klass', - CgOp::cast('DynObject', CgOp::fetch(CgOp::scopedlex('List'))))), - 'DynObject', sub { + CgOp::cast('DynObject', CgOp::fetch(CgOp::scopedlex('List'))))), sub { my $do = shift; CgOp::prog( CgOp::setindex('flat', CgOp::getfield('slots', $do), diff --git a/Unit.pm b/Unit.pm index fd329c47..b18c66d7 100644 --- a/Unit.pm +++ b/Unit.pm @@ -20,7 +20,7 @@ use 5.010; my ($self) = @_; $self->mainline->outer($self->setting) if $self->setting; CodeGen->new(name => 'BOOT', entry => 1, - ops => CgOp::letn('protopad', 'Frame', + ops => CgOp::letn('protopad', CgOp::cast('Frame', CgOp::fetch(CgOp::pos(0))), CgOp::return( CgOp::newscalar(