summaryrefslogtreecommitdiffstats
path: root/core.xs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-07-08 03:01:49 -0500
committerJesse Luehrs <doy@tozt.net>2011-07-08 03:01:49 -0500
commit1a0c3c3a02da09abc11bbad291d09a41c1850d1d (patch)
treec19787eda8fa4dd155e028752cc38bc19dad0aca /core.xs
parent046119999e010e4a38b67f5f194baaf60e7c8707 (diff)
downloadsmartmatch-engine-core-1a0c3c3a02da09abc11bbad291d09a41c1850d1d.tar.gz
smartmatch-engine-core-1a0c3c3a02da09abc11bbad291d09a41c1850d1d.zip
split this out into its own dist, and implement the custom opcode
Diffstat (limited to 'core.xs')
-rw-r--r--core.xs44
1 files changed, 44 insertions, 0 deletions
diff --git a/core.xs b/core.xs
new file mode 100644
index 0000000..3f12ea2
--- /dev/null
+++ b/core.xs
@@ -0,0 +1,44 @@
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include "ppport.h"
+
+#include "stolen_chunk_of_pp_ctl.c"
+
+STATIC OP*
+install_sm_op(pTHX_ OP *o, GV *gv, SV *ud)
+{
+ OP *list, *left, *right, *new;
+
+ list = cUNOPo->op_first;
+ left = cLISTOPx(list)->op_first->op_sibling; /* skip over the pushmark */
+ right = left->op_sibling;
+
+ cLISTOPx(list)->op_first->op_sibling = right->op_sibling;
+ left->op_sibling = right->op_sibling = NULL;
+ op_free(o);
+
+ new = newBINOP(OP_CUSTOM, 0, left, right);
+ new->op_ppaddr = INT2PTR(Perl_ppaddr_t, Perl_pp_old_smartmatch);
+
+ return new;
+}
+
+MODULE = smartmatch::engine::core PACKAGE = smartmatch::engine::core
+
+PROTOTYPES: DISABLE
+
+void
+init(match)
+ SV *match;
+ PREINIT:
+ CV *cv;
+ CODE:
+ if (!SvROK(match) || SvTYPE(SvRV(match)) != SVt_PVCV) {
+ croak("not a coderef");
+ }
+
+ cv = (CV*)SvRV(match);
+
+ cv_set_call_checker(cv, install_sm_op, (SV*)cv);