summaryrefslogtreecommitdiffstats
path: root/Try.xs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2012-08-18 15:08:00 -0500
committerJesse Luehrs <doy@tozt.net>2012-08-18 16:25:59 -0500
commit93dd811c1233c3e9d28d92a56166436a81c3e854 (patch)
tree56710060e64212f37f85a651c5174c3523bd5bb1 /Try.xs
parente590eb7516d6c3533254fb85699473e43ac9c8d8 (diff)
downloadtry-93dd811c1233c3e9d28d92a56166436a81c3e854.tar.gz
try-93dd811c1233c3e9d28d92a56166436a81c3e854.zip
first implementation
Diffstat (limited to 'Try.xs')
-rw-r--r--Try.xs82
1 files changed, 82 insertions, 0 deletions
diff --git a/Try.xs b/Try.xs
new file mode 100644
index 0000000..59f9b64
--- /dev/null
+++ b/Try.xs
@@ -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);
+}