Skip to content

Commit

Permalink
If a constant foldable expression throws an exception, treat it as a …
Browse files Browse the repository at this point in the history
…compile error.
  • Loading branch information
sorear committed Feb 4, 2012
1 parent 2ea3308 commit 2762955
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 26 deletions.
4 changes: 3 additions & 1 deletion lib/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3834,7 +3834,9 @@ public static object unit_constant_fold(object[] args) {
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) {
Expand Down
30 changes: 15 additions & 15 deletions src/NieczaActions.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -1413,7 +1413,7 @@ method circumfix:sym<{ }> ($/) {
if self.check_hash($/) {
make mkcall($/, '&_hash_constructor',
$OptBeta.make_call($var));
$OptBeta.make_call($/, $var));
}
}
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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>);
Expand All @@ -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));
}
Expand Down Expand Up @@ -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;
Expand All @@ -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) ]);
}
Expand Down Expand Up @@ -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 => $_) ]));
}
});
Expand Down Expand Up @@ -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> ) ] }
Expand Down Expand Up @@ -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) ]);
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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($/));
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/NieczaPassSimplifier.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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]);
Expand Down
16 changes: 8 additions & 8 deletions src/Op.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -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($) { }

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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($/));
}
}

Expand Down Expand Up @@ -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);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/OptBeta.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 2762955

Please sign in to comment.