I know KJS already answered this, but I wanted to try to clarify a
bit, and focus just on exception handling in PIR.

Basically, each opcode can throw an exception. If that happens,
control will unwind until it finds something willing to catch it:

.sub 'eek'
  $I0 = 1
  $I0 /= 0
  say $I0
.end

This throws an exception, and since we don't have a "try/catch" setup,
the exception ends up killing parrot itself. If we setup our try/catch
equivalent, we can use a label in the same .sub, and with some gotos,
even have ourselves try/catch/finally, if we care to.

.sub 'eek'
 try:
  push_eh catch
    $I0 = 1
    $I0 /=0
  pop_eh
  goto finally
 catch:
   say "caught an exception."
 finally:
   say $I0
.end

Note that we don't really need to examine the exception at all, if we
don't want to. The flow here sets $I0, the next opcode throws an
exception, at which point execution goes to the catch handler we
registered (at the catch: label). We print our message, then fall
through to the finally block. (If we change this to a /= 1, we see
that we exit the try "block", hit the goto, and then just print our
value.)

If you do want to examine the exception, we can replace it with something like:

  catch:
   .local pmc e, msg
   .get_results(e, msg)
   print "caught an exception of severity: "
   $I1 = e['_severity']
   say $I1


As KJS noted, the second parameter is just the '_message' slot of
exceptions. (NB: This method of accessing exception information is
deprecated, and will eventually be done with getattribute: see
RT#48012).

So, the .get_results() doesn't actually *catch* the exception: it's
basically a shorthand for dealing with the calling conventions, as all
exception handlers are basically declared as taking two parameters.
(none is ok, but if you take any, you have to take both, at least for
now.)

This is also covered (more briefly) in docs/compiler_faq.pod

Regards, hope this helps.

On Thu, Mar 27, 2008 at 1:48 PM, Ovid
<[EMAIL PROTECTED]> wrote:
> Hi all,
>
>  Trying to work through the tutorial
>  (http://www.parrotblog.org/search/label/tutorial) and am trying to
>  finish Episode 4 with catch blocks.  The grammar in Episode 3 has this:
>
>   try-statement ::= 'try' block 'catch' identifier
>                     block
>                     'end'
>
>  I've translated it to this:
>
>   rule try_statement {
>     'try'   <block>
>     'catch' <identifier> $<catch_block>=<block>
>     'end'
>     {*}
>   }
>
>  In searching through code, I've come up with this method for that:
>
>   method try_statement($/) {
>       my $try        := $( $<block> );
>       my $identifier := $( $<identifier> );
>       my $catch      := $( $<catch_block> );
>
>       my $past := PAST::Op.new(
>           :pasttype('try'),
>           :node($/)
>       );
>       $past.push($try);
>
>       # Create the catch
>       my $catchpir := "    .get_results (%r, $S0)\n    store_lex '" ~
>  $identifier.name() ~ "', %r";
>       $catch.unshift( PAST::Op.new( :inline( $catchpir ) ) );
>
>       $past.push($catch);
>       make $past;
>   }
>
>  However, when I try it with this: "try x=4 catch e y=2 end", my pir
>  doesn't appear to have any logic to catch an exception (or I just know
>  pir very well).  Also, how do I know that the exception object is in
>  $S0?  My pir is below.  Is this actually correct and all will become
>  clear later?
>
>  Cheers,
>  Ovid
>
>  .namespace
>  .sub "_block10"
>     push_eh catch_11
>     get_global $P15, "_block12"
>     newclosure $P15, $P15
>     $P14 = $P15()
>     pop_eh
>     goto catch_11_end
>   catch_11:
>     get_global $P19, "_block16"
>     newclosure $P19, $P19
>     $P19()
>   catch_11_end:
>     .return ($P14)
>  .end
>
>
>  .namespace
>  .sub "_block16"  :outer("_block10")
>     .get_results ($P17, $S0)
>     store_lex 'e', $P17
>     new $P18, "Integer"
>     assign $P18, 2
>     set_global "y", $P18
>     .return ($P18)
>  .end
>
>
>  .namespace
>  .sub "_block12"  :outer("_block10")
>     new $P13, "Integer"
>     assign $P13, 4
>     set_global "x", $P13
>     .return ($P13)
>  .end
>
>
>  --
>  Buy the book  - http://www.oreilly.com/catalog/perlhks/
>  Perl and CGI  - http://users.easystreet.com/ovid/cgi_course/
>  Personal blog - http://publius-ovidius.livejournal.com/
>  Tech blog     - http://use.perl.org/~Ovid/journal/
>
>



-- 
Will "Coke" Coleda

Reply via email to