Permalink
Browse files

If a constant foldable expression throws an exception, treat it as a …

…compile error.
  • Loading branch information...
1 parent 2ea3308 commit 2762955c3b82394f8492261a3590213b8c525efa @sorear committed Feb 4, 2012
Showing with 39 additions and 26 deletions.
  1. +3 −1 lib/CodeGen.cs
  2. +15 −15 src/NieczaActions.pm6
  3. +11 −0 src/NieczaPassSimplifier.pm6
  4. +8 −8 src/Op.pm6
  5. +2 −2 src/OptBeta.pm6
View
@@ -3834,7 +3834,9 @@ public class DowncallReceiver : CallReceiver {
try {
r = Handle.Wrap(Kernel.RunInferior(callee.protosub.Invoke(
Kernel.GetInferiorRoot(), pos.ToArray(), nam)));
- } catch (Exception) { }
+ } catch (Exception ex) {
+ r = ex.ToString();
+ }
return r;
}
public static object unit_string_constant(object[] args) {
View
@@ -1000,7 +1000,7 @@ method assertion:name ($/) {
my $callop;
if $is_lexical {
- $callop = $OpCallSub.new(invocant => mklex($/, "&$name"),
+ $callop = $OpCallSub.new(pos=>$/, invocant => mklex($/, "&$name"),
positionals => [ mklex($/, ''), @$args ]);
} elsif $pname<iname> {
$callop = $Operator_Method.new(name => $pname<iname>, :$args,
@@ -1413,7 +1413,7 @@ method circumfix:sym<{ }> ($/) {
if self.check_hash($/) {
make mkcall($/, '&_hash_constructor',
- $OptBeta.make_call($var));
+ $OptBeta.make_call($/, $var));
}
}
@@ -1530,7 +1530,7 @@ method statement_control:TEMP ($/) {
# now that initializer has been split out this can be a lot smaller...
method INFIX($/) {
my $fn = $<infix>.ast;
- my ($st,$lhs,$rhs) = self.whatever_precheck($fn, $<left>.ast, $<right>.ast);
+ my ($st,$lhs,$rhs) = self.whatever_precheck($/, $fn, $<left>.ast, $<right>.ast);
make $fn.with_args($/, $lhs, $rhs);
make self.whatever_postcheck($/, $st, $/.ast);
@@ -1546,7 +1546,7 @@ method CHAIN($/) {
push @ops, $<chain>[$i++]<infix>.ast;
}
- my ($st, @vargs) = self.whatever_precheck(@ops[0], @args);
+ my ($st, @vargs) = self.whatever_precheck($/, @ops[0], @args);
sub reduce($/) {
my $fa = shift @vargs;
@@ -1572,15 +1572,15 @@ method LIST($/) {
# STD guarantees that all elements of delims have the same sym
# the last item may have an ast of undef due to nulltermish
my $fn = $<delims>[0].ast;
- my ($st, @pos) = self.whatever_precheck($fn,
+ my ($st, @pos) = self.whatever_precheck($/, $fn,
grep *.&defined, map *.ast, @( $<list> ));
make self.whatever_postcheck($/, $st, $fn.with_args($/, @pos));
}
method POSTFIX($/) {
# adverbs have undef ast
- my ($st, $arg) = self.whatever_precheck($<op>.ast // '', $<arg>.ast);
+ my ($st, $arg) = self.whatever_precheck($/, $<op>.ast // '', $<arg>.ast);
if $<op><colonpair> {
if $arg.^isa($OpCallLike) {
make $arg.adverb($<op><colonpair>.ast<term>);
@@ -1596,7 +1596,7 @@ method POSTFIX($/) {
}
method PREFIX($/) {
- my ($st, $arg) = self.whatever_precheck($<op>.ast, $<arg>.ast);
+ my ($st, $arg) = self.whatever_precheck($/, $<op>.ast, $<arg>.ast);
make self.whatever_postcheck($/, $st, $<op>.ast.with_args($/, $arg));
}
@@ -1773,7 +1773,7 @@ method fatarrow($/) {
my %_nowhatever = (map { ($_ => True) }, ('&infix:<,>', '&infix:<..>',
'&infix:<...>', '&infix:<=>', '&infix:<xx>'));
-method whatever_precheck($op, *@args) {
+method whatever_precheck($/, $op, *@args) {
return ([], @args) if ($op.^isa($Operator) ?? !$op.whatever_curry !! %_nowhatever{$op});
my @vars;
my @args_ = @args;
@@ -1784,7 +1784,7 @@ method whatever_precheck($op, *@args) {
$a = $OpLexical.new(name => $a.slot);
} elsif $a.^isa($OpWhateverCode) {
push @vars, @( $a.vars );
- $a = $OpCallSub.new(
+ $a = $OpCallSub.new(pos=>$/,
invocant => $OpLexical.new(name => $a.slot),
args => [ map { $OpLexical.new(name => $_) }, @($a.vars) ]);
}
@@ -2974,11 +2974,11 @@ method type_declarator:enum ($/) {
for $map.enum_keys {
self.make_constant_into($/, $obj, $_, rhs =>
- $OpCallSub.new(invocant => mklex($/, $lexvar),
+ $OpCallSub.new(pos=>$/, invocant => mklex($/, $lexvar),
args => [ $OpStringLiteral.new(text => $_) ]));
self.init_constant(self.make_constant($/, $scope, $_),
- $OpCallSub.new(invocant => mklex($/, $lexvar),
+ $OpCallSub.new(pos=>$/, invocant => mklex($/, $lexvar),
args => [ $OpStringLiteral.new(text => $_) ]));
}
});
@@ -3277,7 +3277,7 @@ method statement_mod_loop:given ($/) { self.statement_mod_loop($/) }
method statementlist($/) {
make $OpStatementList.new(pos=>$/, children =>
- [ map *.statement_level, map *.ast, @( $<statement> ) ]);
+ [ map *.statement_level($/), map *.ast, @( $<statement> ) ]);
}
method semilist($/) { make [ map *.ast, @( $<statement> ) ] }
@@ -3585,7 +3585,7 @@ method package_def ($/) {
make mklex($/, $*CURLEX<!sub>.outervar);
} else {
make $OpStatementList.new(pos=>$/, children => [
- $OpCallSub.new(invocant => mklex($/, $bodyvar)),
+ $OpCallSub.new(pos=>$/, invocant => mklex($/, $bodyvar)),
$OpLexical.new(name => $*CURLEX<!sub>.outervar) ]);
}
}
@@ -3675,7 +3675,7 @@ method block_expr($/, $pb) {
method inliney_call($/, $block, *@parms) {
my $sym = self.gensym;
$*CURLEX<!sub>.add_my_sub($sym, $block);
- $OptBeta.make_call($sym, @parms);
+ $OptBeta.make_call($/, $sym, @parms);
}
# this is intended to be called after parsing the longname for a sub,
@@ -3938,7 +3938,7 @@ method blast($/) {
if $<block> {
make $<block>.ast;
} else {
- make self.thunk_sub($<statement>.ast.statement_level);
+ make self.thunk_sub($<statement>.ast.statement_level($/));
}
}
@@ -15,9 +15,15 @@ method invoke($*unit) {
}
method invoke_incr($sub, $ops) {
+ my $*where = False;
run_optree($sub, $ops, 1);
}
+sub sorry($msg) {
+ die "No position info to report ($msg)" unless $*where;
+ $*where.CURSOR.sorry($msg);
+}
+
sub no_named_params($op) {
if defined $op.args {
for @( $op.args ) -> $a {
@@ -138,12 +144,17 @@ sub check_folding($body, $sub, $op) {
}
my $ret = $*unit.constant_fold($sub, @evargs) // return;
+ if $ret.^isa(Str) {
+ sorry "Constant folding threw exception: $ret";
+ return;
+ }
$OpGeneralConst.new(value => $ret);
}
sub run_optree($body, $op, $nv) {
die "WTF in $body.name()" if !defined $op;
my @kids := flat($op.ctxzyg($nv));
+ temp $*where; $*where = $op.pos // $*where;
my $i = 0;
while $i < @kids {
@kids[$i] = run_optree($body, @kids[$i], @kids[$i+1]);
View
@@ -46,7 +46,7 @@ method cgop_labelled($body, $label) {
method code_labelled($body, $label) { self.code($body) } #OK not used
-method statement_level() { self }
+method statement_level($/) { self }
method onlystub() { False }
method const_value($) { }
@@ -146,7 +146,7 @@ class CallSub is CallLike {
method zyg() { $.invocant, @( $.args // $.positionals ) } # XXX callsame
method adverb($adv) {
- $OpCallSub.new(invocant => $.invocant, args => [ self.getargs, $adv ])
+ $OpCallSub.new(pos => $.pos, invocant => $.invocant, args => [ self.getargs, $adv ])
}
method code($body) {
@@ -495,12 +495,12 @@ class ForLoop is Op {
$.source.cgop($body)), 'map', $CgOp.scopedlex($!sin));
}
- method statement_level() {
+ method statement_level($/) {
my $body = $*CURLEX<!sub>.lookup_lex($!sink)[4];
my $var = [ map { $Actions.gensym },
0 ..^ $body.count ];
$OpImmedForLoop.new(source => $!source, var => $var,
- sink => $OptBeta.make_call($!sink,
+ sink => $OptBeta.make_call($/, $!sink,
map { $OpLetVar.new(name => $_) }, @$var));
}
}
@@ -549,8 +549,8 @@ class Labelled is Op {
$CgOp.prog($CgOp.label("goto_$.name"),$.stmt.cgop_labelled($body,$.name));
}
- method statement_level() {
- self.new(name => $.name, stmt => $.stmt.statement_level);
+ method statement_level($/) {
+ self.new(name => $.name, stmt => $.stmt.statement_level($/));
}
}
@@ -666,9 +666,9 @@ class BareBlock is Op {
method code($) { $CgOp.scopedlex($!var) }
- method statement_level() {
+ method statement_level($/) {
$*CURLEX<!sub>.lookup_lex($!var).[4].set_run_once;
- $OptBeta.make_call($!var);
+ $OptBeta.make_call($/, $!var);
}
}
View
@@ -6,8 +6,8 @@ class OptBeta;
# (-> $x { block })($y), due to control structures and regexes. Try to clean
# that up here.
-method make_call($var, *@params) {
- my $nonopt = $OpCallSub.new(
+method make_call($/, $var, *@params) {
+ my $nonopt = $OpCallSub.new(pos=>$/,
positionals => [ @params ],
invocant => $OpLexical.new(name => $var));
my @lex = $*CURLEX<!sub>.lookup_lex($var) or return $nonopt;

0 comments on commit 2762955

Please sign in to comment.