summaryrefslogtreecommitdiff
path: root/ext/XS-APItest
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2010-10-04 22:19:08 +0100
committerFather Chrysostomos <sprout@cpan.org>2010-10-12 12:52:12 -0700
commit2fcb4757c157c580cb9ddfcd3da7f1b3795d62a8 (patch)
treec1bd54a7dfc6549029adacc483327aa128f32dab /ext/XS-APItest
parentd056e33c1ea02abb0c031adb18b181624282ba3c (diff)
downloadperl-2fcb4757c157c580cb9ddfcd3da7f1b3795d62a8.tar.gz
APIify op list constructors
Put into the API op_append_elem, op_prepend_elem, and op_append_list. All renamed from op_-less internal names. Parameter types for op_append_list changed to match the rest of the op API and avoid some casting.
Diffstat (limited to 'ext/XS-APItest')
-rw-r--r--ext/XS-APItest/APItest.xs150
-rw-r--r--ext/XS-APItest/t/op_list.t10
2 files changed, 158 insertions, 2 deletions
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 9f0304ecf1..cadfaa4896 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -418,6 +418,36 @@ THX_ck_entersub_multi_sum(pTHX_ OP *entersubop, GV *namegv, SV *ckobj)
return sumop;
}
+STATIC void test_op_list_describe_part(SV *res, OP *o);
+STATIC void
+test_op_list_describe_part(SV *res, OP *o)
+{
+ sv_catpv(res, PL_op_name[o->op_type]);
+ switch (o->op_type) {
+ case OP_CONST: {
+ sv_catpvf(res, "(%d)", (int)SvIV(cSVOPx(o)->op_sv));
+ } break;
+ }
+ if (o->op_flags & OPf_KIDS) {
+ OP *k;
+ sv_catpvs(res, "[");
+ for (k = cUNOPx(o)->op_first; k; k = k->op_sibling)
+ test_op_list_describe_part(res, k);
+ sv_catpvs(res, "]");
+ } else {
+ sv_catpvs(res, ".");
+ }
+}
+
+STATIC char *
+test_op_list_describe(OP *o)
+{
+ SV *res = sv_2mortal(newSVpvs(""));
+ if (o)
+ test_op_list_describe_part(res, o);
+ return SvPVX(res);
+}
+
/** RPN keyword parser **/
#define sv_is_glob(sv) (SvTYPE(sv) == SVt_PVGV)
@@ -595,8 +625,7 @@ static OP *THX_parse_keyword_swaptwostmts(pTHX)
b = parse_fullstmt(0);
if(a && b)
PL_hints |= HINT_BLOCK_SCOPE;
- /* should use append_list(), but that's not part of the public API */
- return !a ? b : !b ? a : newLISTOP(OP_LINESEQ, 0, b, a);
+ return op_append_list(OP_LINESEQ, b, a);
}
#define parse_keyword_looprest() THX_parse_keyword_looprest(aTHX)
@@ -1790,6 +1819,123 @@ test_copyhints()
LEAVE;
void
+test_op_list()
+ PREINIT:
+ OP *a;
+ CODE:
+#define iv_op(iv) newSVOP(OP_CONST, 0, newSViv(iv))
+#define check_op(o, expect) \
+ do { \
+ if (strcmp(test_op_list_describe(o), (expect))) \
+ croak("fail %s %s", test_op_list_describe(o), (expect)); \
+ } while(0)
+ a = op_append_elem(OP_LIST, NULL, NULL);
+ check_op(a, "");
+ a = op_append_elem(OP_LIST, iv_op(1), a);
+ check_op(a, "const(1).");
+ a = op_append_elem(OP_LIST, NULL, a);
+ check_op(a, "const(1).");
+ a = op_append_elem(OP_LIST, a, iv_op(2));
+ check_op(a, "list[pushmark.const(1).const(2).]");
+ a = op_append_elem(OP_LIST, a, iv_op(3));
+ check_op(a, "list[pushmark.const(1).const(2).const(3).]");
+ a = op_append_elem(OP_LIST, a, NULL);
+ check_op(a, "list[pushmark.const(1).const(2).const(3).]");
+ a = op_append_elem(OP_LIST, NULL, a);
+ check_op(a, "list[pushmark.const(1).const(2).const(3).]");
+ a = op_append_elem(OP_LIST, iv_op(4), a);
+ check_op(a, "list[pushmark.const(4)."
+ "list[pushmark.const(1).const(2).const(3).]]");
+ a = op_append_elem(OP_LIST, a, iv_op(5));
+ check_op(a, "list[pushmark.const(4)."
+ "list[pushmark.const(1).const(2).const(3).]const(5).]");
+ a = op_append_elem(OP_LIST, a,
+ op_append_elem(OP_LIST, iv_op(7), iv_op(6)));
+ check_op(a, "list[pushmark.const(4)."
+ "list[pushmark.const(1).const(2).const(3).]const(5)."
+ "list[pushmark.const(7).const(6).]]");
+ op_free(a);
+ a = op_append_elem(OP_LINESEQ, iv_op(1), iv_op(2));
+ check_op(a, "lineseq[const(1).const(2).]");
+ a = op_append_elem(OP_LINESEQ, a, iv_op(3));
+ check_op(a, "lineseq[const(1).const(2).const(3).]");
+ op_free(a);
+ a = op_append_elem(OP_LINESEQ,
+ op_append_elem(OP_LIST, iv_op(1), iv_op(2)),
+ iv_op(3));
+ check_op(a, "lineseq[list[pushmark.const(1).const(2).]const(3).]");
+ op_free(a);
+ a = op_prepend_elem(OP_LIST, NULL, NULL);
+ check_op(a, "");
+ a = op_prepend_elem(OP_LIST, a, iv_op(1));
+ check_op(a, "const(1).");
+ a = op_prepend_elem(OP_LIST, a, NULL);
+ check_op(a, "const(1).");
+ a = op_prepend_elem(OP_LIST, iv_op(2), a);
+ check_op(a, "list[pushmark.const(2).const(1).]");
+ a = op_prepend_elem(OP_LIST, iv_op(3), a);
+ check_op(a, "list[pushmark.const(3).const(2).const(1).]");
+ a = op_prepend_elem(OP_LIST, NULL, a);
+ check_op(a, "list[pushmark.const(3).const(2).const(1).]");
+ a = op_prepend_elem(OP_LIST, a, NULL);
+ check_op(a, "list[pushmark.const(3).const(2).const(1).]");
+ a = op_prepend_elem(OP_LIST, a, iv_op(4));
+ check_op(a, "list[pushmark."
+ "list[pushmark.const(3).const(2).const(1).]const(4).]");
+ a = op_prepend_elem(OP_LIST, iv_op(5), a);
+ check_op(a, "list[pushmark.const(5)."
+ "list[pushmark.const(3).const(2).const(1).]const(4).]");
+ a = op_prepend_elem(OP_LIST,
+ op_prepend_elem(OP_LIST, iv_op(6), iv_op(7)), a);
+ check_op(a, "list[pushmark.list[pushmark.const(6).const(7).]const(5)."
+ "list[pushmark.const(3).const(2).const(1).]const(4).]");
+ op_free(a);
+ a = op_prepend_elem(OP_LINESEQ, iv_op(2), iv_op(1));
+ check_op(a, "lineseq[const(2).const(1).]");
+ a = op_prepend_elem(OP_LINESEQ, iv_op(3), a);
+ check_op(a, "lineseq[const(3).const(2).const(1).]");
+ op_free(a);
+ a = op_prepend_elem(OP_LINESEQ, iv_op(3),
+ op_prepend_elem(OP_LIST, iv_op(2), iv_op(1)));
+ check_op(a, "lineseq[const(3).list[pushmark.const(2).const(1).]]");
+ op_free(a);
+ a = op_append_list(OP_LINESEQ, NULL, NULL);
+ check_op(a, "");
+ a = op_append_list(OP_LINESEQ, iv_op(1), a);
+ check_op(a, "const(1).");
+ a = op_append_list(OP_LINESEQ, NULL, a);
+ check_op(a, "const(1).");
+ a = op_append_list(OP_LINESEQ, a, iv_op(2));
+ check_op(a, "lineseq[const(1).const(2).]");
+ a = op_append_list(OP_LINESEQ, a, iv_op(3));
+ check_op(a, "lineseq[const(1).const(2).const(3).]");
+ a = op_append_list(OP_LINESEQ, iv_op(4), a);
+ check_op(a, "lineseq[const(4).const(1).const(2).const(3).]");
+ a = op_append_list(OP_LINESEQ, a, NULL);
+ check_op(a, "lineseq[const(4).const(1).const(2).const(3).]");
+ a = op_append_list(OP_LINESEQ, NULL, a);
+ check_op(a, "lineseq[const(4).const(1).const(2).const(3).]");
+ a = op_append_list(OP_LINESEQ, a,
+ op_append_list(OP_LINESEQ, iv_op(5), iv_op(6)));
+ check_op(a, "lineseq[const(4).const(1).const(2).const(3)."
+ "const(5).const(6).]");
+ op_free(a);
+ a = op_append_list(OP_LINESEQ,
+ op_append_list(OP_LINESEQ, iv_op(1), iv_op(2)),
+ op_append_list(OP_LIST, iv_op(3), iv_op(4)));
+ check_op(a, "lineseq[const(1).const(2)."
+ "list[pushmark.const(3).const(4).]]");
+ op_free(a);
+ a = op_append_list(OP_LINESEQ,
+ op_append_list(OP_LIST, iv_op(1), iv_op(2)),
+ op_append_list(OP_LINESEQ, iv_op(3), iv_op(4)));
+ check_op(a, "lineseq[list[pushmark.const(1).const(2).]"
+ "const(3).const(4).]");
+ op_free(a);
+#undef iv_op
+#undef check_op
+
+void
peep_enable ()
PREINIT:
dMY_CXT;
diff --git a/ext/XS-APItest/t/op_list.t b/ext/XS-APItest/t/op_list.t
new file mode 100644
index 0000000000..e5b55a93c9
--- /dev/null
+++ b/ext/XS-APItest/t/op_list.t
@@ -0,0 +1,10 @@
+use warnings;
+use strict;
+use Test::More tests => 1;
+
+use XS::APItest;
+
+XS::APItest::test_op_list();
+ok 1;
+
+1;