Skip to content

Commit

Permalink
typed exception for returning outside of a routine
Browse files Browse the repository at this point in the history
  • Loading branch information
moritz committed May 15, 2012
1 parent 4687e02 commit 38ea7c2
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
19 changes: 17 additions & 2 deletions src/core/Exception.pm
Expand Up @@ -608,6 +608,18 @@ my class X::Sequence::Deduction is Exception {
method message() { 'Unable to deduce sequence' }
}

my class X::ControlFlow is Exception {
has $.illegal; # something like 'next'
has $.enclosing; # .... outside a loop

method message() { "$.illegal without $.enclosing" }
}
my class X::ControlFlow::Return is X::ControlFlow {
method illegal() { 'return' }
method enclosing() { 'Routine' }
method message() { 'Attempt to return outside of any Routine' }
}

my class X::TypeCheck is Exception {
has $.operation;
has $.got;
Expand All @@ -630,12 +642,15 @@ my class X::TypeCheck::Return is X::TypeCheck {

{
my %c_ex;
%c_ex{'X::TypeCheck::Binding'} := sub ($got, $expected) {
%c_ex{'X::TypeCheck::Binding'} := sub ($got, $expected) is hidden_from_backtrace {
X::TypeCheck::Binding.new(:$got, :$expected).throw;
};
%c_ex{'X::TypeCheck::Return'} := sub ($got, $expected) {
%c_ex{'X::TypeCheck::Return'} := sub ($got, $expected) is hidden_from_backtrace {
X::TypeCheck::Return.new(:$got, :$expected).throw;
};
%c_ex{'X::ControlFlow::Return'} := sub () is hidden_from_backtrace {
X::ControlFlow::Return.new().throw;
};
my Mu $parrot_c_ex := nqp::getattr(%c_ex, EnumMap, '$!storage');
pir::set_hll_global__vsP('P6EX', $parrot_c_ex);
0;
Expand Down
8 changes: 6 additions & 2 deletions src/ops/perl6.ops
Expand Up @@ -1828,8 +1828,12 @@ inline op perl6_return_from_routine(in PMC) :flow {
}
}
if (PMC_IS_NULL(cont)) {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Attempt to return outside of any Routine");
PMC * const thrower = get_thrower(interp, "X::ControlFlow::Return");
if (PMC_IS_NULL(thrower))
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Attempt to return outside of any Routine");
else
Parrot_pcc_invoke_sub_from_c_args(interp, thrower, "->");
}
ctx = CURRENT_CONTEXT(interp);
GETATTR_Continuation_to_ctx(interp, cont, cctx);
Expand Down

0 comments on commit 38ea7c2

Please sign in to comment.