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