On Thu, Mar 27, 2008 at 6: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'
>     {*}
>   }

I did this myself the first time, but I got into problems, couldn't
get this working. Not sure why.
In any case, in my own implementation, the catch block is written (in
the grammar) as <statement>*, not <block>.
I posted my implementation a few days ago to the list; you could check
that for yourself.

>
>  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).

See marker "[1]" below. The PIR that does the catching of the
exception is ".get_results..." (this is the string in $catchpir,
above)

The action method looks pretty good to me, except that it won't run (I
think). the "store_lex 'e' ... " will fail (in my experience) because
"e" wasn't declared as a ".lex". Again, see the reference
implementation that was sent to the mailing list.

So, what I did myself was, also adding a PAST::Var to the catch block,
that specifies a "lexical" (scope) that has the name of the exception
object (don't reuse the PAST node for the exception identifier), and
set the "isdecl" flag on it.




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?

So, catching an exception in Parrot is done like this:

.get_results($P0, $S0)

where the actual exception object (printing the output of the "typeof"
instr will print "Exception") is stored in $P0, and the exception
message is stored in $S0. So, Parrot always (currently!) provides 2
things: the exceptino object and the exception message. The message
can actually be retrieved from the exception object, so it seems
superfluous. I don't know why it is implemented like this (but my
personal preference would be to remove the need for $S0). In any case,
$S0 is just a dummy, we don't use the message, just using the
exception object (which will be stored in $P0) is fine.


hope this helps, let me know if you're still having trouble.
kjs

>
>  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")

[1]:
============================
>     .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/
>

Reply via email to