diff options
author | Jesse Luehrs <doy@tozt.net> | 2012-08-18 15:08:00 -0500 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2012-08-18 16:25:59 -0500 |
commit | 93dd811c1233c3e9d28d92a56166436a81c3e854 (patch) | |
tree | 56710060e64212f37f85a651c5174c3523bd5bb1 /Try.xs | |
parent | e590eb7516d6c3533254fb85699473e43ac9c8d8 (diff) | |
download | try-93dd811c1233c3e9d28d92a56166436a81c3e854.tar.gz try-93dd811c1233c3e9d28d92a56166436a81c3e854.zip |
first implementation
Diffstat (limited to 'Try.xs')
-rw-r--r-- | Try.xs | 82 |
1 files changed, 82 insertions, 0 deletions
@@ -0,0 +1,82 @@ +#include "EXTERN.h" +#include "perl.h" +#include "callparser1.h" +#include "XSUB.h" + +static int check_keyword(const char *keyword) +{ + STRLEN len; + + len = strlen(keyword); + if (PL_parser->bufend - PL_parser->bufptr < len) { + return 0; + } + + if (strnNE(PL_parser->bufptr, keyword, len)) { + return 0; + } + + if (PL_parser->bufptr + len != PL_parser->bufend + && isALNUM(*(PL_parser->bufptr + len))) { + return 0; + } + + lex_read_to(PL_parser->bufptr + len); + + return 1; +} + +static OP *parse_try(pTHX_ GV *namegv, SV *psobj, U32 *flagsp) +{ + OP *try, *catch, *finally, *ret; + I32 floor; + + *flagsp |= CALLPARSER_STATEMENT; + + lex_read_space(0); + if (*(PL_parser->bufptr) != '{') { + croak("syntax error"); + } + floor = start_subparse(0, CVf_ANON); + try = newANONSUB(floor, NULL, parse_block(0)); + + lex_read_space(0); + if (check_keyword("catch")) { + lex_read_space(0); + if (*(PL_parser->bufptr) != '{') { + croak("syntax error"); + } + floor = start_subparse(0, CVf_ANON); + catch = newANONSUB(floor, NULL, parse_block(0)); + } + else { + catch = newOP(OP_UNDEF, 0); + } + + lex_read_space(0); + if (check_keyword("finally")) { + lex_read_space(0); + if (*(PL_parser->bufptr) != '{') { + croak("syntax error"); + } + floor = start_subparse(0, CVf_ANON); + finally = newANONSUB(floor, NULL, parse_block(0)); + } + else { + finally = newOP(OP_UNDEF, 0); + } + + ret = newLISTOP(OP_LIST, 0, try, catch); + op_append_elem(OP_LIST, ret, finally); + + return ret; +} + +MODULE = Try PACKAGE = Try + +PROTOTYPES: DISABLE + +BOOT: +{ + cv_set_call_parser(get_cv("Try::try", 0), parse_try, &PL_sv_undef); +} |