diff options
Diffstat (limited to 'ext/XS-APItest-KeywordRPN')
-rw-r--r-- | ext/XS-APItest-KeywordRPN/KeywordRPN.pm | 143 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/KeywordRPN.xs | 308 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/Makefile.PL | 17 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/README | 25 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/t/keyword_plugin.t | 76 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/t/multiline.t | 27 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/t/stuff_svcur_bug.t | 12 | ||||
-rw-r--r-- | ext/XS-APItest-KeywordRPN/t/swaptwostmts.t | 158 |
8 files changed, 0 insertions, 766 deletions
diff --git a/ext/XS-APItest-KeywordRPN/KeywordRPN.pm b/ext/XS-APItest-KeywordRPN/KeywordRPN.pm deleted file mode 100644 index 224faf773d..0000000000 --- a/ext/XS-APItest-KeywordRPN/KeywordRPN.pm +++ /dev/null @@ -1,143 +0,0 @@ -=head1 NAME - -XS::APItest::KeywordRPN - write arithmetic expressions in RPN - -=head1 SYNOPSIS - - use XS::APItest::KeywordRPN qw(rpn calcrpn); - - $triangle = rpn($n $n 1 + * 2 /); - - calcrpn $triangle { $n $n 1 + * 2 / } - -=head1 DESCRIPTION - -This module supplies plugged-in keywords, using the new mechanism in Perl -5.11.2, that allow arithmetic to be expressed in reverse Polish notation, -in an otherwise Perl program. This module has serious limitations and -is not intended for real use: its purpose is only to test the keyword -plugin mechanism. For that purpose it is part of the Perl core source -distribution, and is not meant to be installed. - -=head2 RPN expression syntax - -Tokens of an RPN expression may be separated by whitespace, but such -separation is usually not required. It is required only where unseparated -tokens would look like a longer token. For example, C<12 34 +> can be -written as C<12 34+>, but not as C<1234 +>. - -An RPN expression may be any of: - -=over - -=item C<1234> - -A sequence of digits is an unsigned decimal literal number. - -=item C<$foo> - -An alphanumeric name preceded by dollar sign refers to a Perl scalar -variable. Only variables declared with C<my> or C<state> are supported. -If the variable's value is not a native integer, it will be converted -to an integer, by Perl's usual mechanisms, at the time it is evaluated. - -=item I<A> I<B> C<+> - -Sum of I<A> and I<B>. - -=item I<A> I<B> C<-> - -Difference of I<A> and I<B>, the result of subtracting I<B> from I<A>. - -=item I<A> I<B> C<*> - -Product of I<A> and I<B>. - -=item I<A> I<B> C</> - -Quotient when I<A> is divided by I<B>, rounded towards zero. -Division by zero generates an exception. - -=item I<A> I<B> C<%> - -Remainder when I<A> is divided by I<B> with the quotient rounded towards zero. -Division by zero generates an exception. - -=back - -Because the arithmetic operators all have fixed arity and are postfixed, -there is no need for operator precedence, nor for a grouping operator -to override precedence. This is half of the point of RPN. - -An RPN expression can also be interpreted in another way, as a sequence -of operations on a stack, one operation per token. A literal or variable -token pushes a value onto the stack. A binary operator pulls two items -off the stack, performs a calculation with them, and pushes the result -back onto the stack. The stack starts out empty, and at the end of the -expression there must be exactly one value left on the stack. - -=cut - -package XS::APItest::KeywordRPN; - -{ use 5.011001; } -use warnings; -use strict; - -our $VERSION = "0.005"; - -require XSLoader; -XSLoader::load(__PACKAGE__, $VERSION); - -=head1 OPERATORS - -These are the operators being added to the Perl language. - -=over - -=item rpn(EXPRESSION) - -This construct is a Perl expression. I<EXPRESSION> must be an RPN -arithmetic expression, as described above. The RPN expression is -evaluated, and its value is returned as the value of the Perl expression. - -=item calcrpn VARIABLE { EXPRESSION } - -This construct is a complete Perl statement. (No semicolon should -follow the closing brace.) I<VARIABLE> must be a Perl scalar C<my> -variable, and I<EXPRESSION> must be an RPN arithmetic expression as -described above. The RPN expression is evaluated, and its value is -assigned to the variable. - -=back - -=head1 BUGS - -This module only performs arithmetic on native integers, and only a -small subset of the arithmetic operations that Perl offers. This is -due to it being intended only for demonstration and test purposes. - -The RPN parser is liable to leak memory when a parse error occurs. -It doesn't leak on success, however. - -=head1 SEE ALSO - -L<Devel::Declare>, -L<perlapi/PL_keyword_plugin> - -=head1 AUTHOR - -Andrew Main (Zefram) <zefram@fysh.org> - -=head1 COPYRIGHT - -Copyright (C) 2009 Andrew Main (Zefram) <zefram@fysh.org> - -=head1 LICENSE - -This module is free software; you can redistribute it and/or modify it -under the same terms as Perl itself. - -=cut - -1; diff --git a/ext/XS-APItest-KeywordRPN/KeywordRPN.xs b/ext/XS-APItest-KeywordRPN/KeywordRPN.xs deleted file mode 100644 index 6c622564ff..0000000000 --- a/ext/XS-APItest-KeywordRPN/KeywordRPN.xs +++ /dev/null @@ -1,308 +0,0 @@ -#include "EXTERN.h" -#include "perl.h" -#include "XSUB.h" - -#define sv_is_glob(sv) (SvTYPE(sv) == SVt_PVGV) -#define sv_is_regexp(sv) (SvTYPE(sv) == SVt_REGEXP) -#define sv_is_string(sv) \ - (!sv_is_glob(sv) && !sv_is_regexp(sv) && \ - (SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK|SVp_IOK|SVp_NOK|SVp_POK))) - -static SV *hintkey_rpn_sv, *hintkey_calcrpn_sv, *hintkey_stufftest_sv; -static SV *hintkey_swaptwostmts_sv; -static int (*next_keyword_plugin)(pTHX_ char *, STRLEN, OP **); - -/* low-level parser helpers */ - -#define PL_bufptr (PL_parser->bufptr) -#define PL_bufend (PL_parser->bufend) - -/* RPN parser */ - -static OP *THX_parse_var(pTHX) -{ - char *s = PL_bufptr; - char *start = s; - PADOFFSET varpos; - OP *padop; - if(*s != '$') croak("RPN syntax error"); - while(1) { - char c = *++s; - if(!isALNUM(c)) break; - } - if(s-start < 2) croak("RPN syntax error"); - lex_read_to(s); - { - /* because pad_findmy() doesn't really use length yet */ - SV *namesv = sv_2mortal(newSVpvn(start, s-start)); - varpos = pad_findmy(SvPVX(namesv), s-start, 0); - } - if(varpos == NOT_IN_PAD || PAD_COMPNAME_FLAGS_isOUR(varpos)) - croak("RPN only supports \"my\" variables"); - padop = newOP(OP_PADSV, 0); - padop->op_targ = varpos; - return padop; -} -#define parse_var() THX_parse_var(aTHX) - -#define push_rpn_item(o) \ - (tmpop = (o), tmpop->op_sibling = stack, stack = tmpop) -#define pop_rpn_item() \ - (!stack ? (croak("RPN stack underflow"), (OP*)NULL) : \ - (tmpop = stack, stack = stack->op_sibling, \ - tmpop->op_sibling = NULL, tmpop)) - -static OP *THX_parse_rpn_expr(pTHX) -{ - OP *stack = NULL, *tmpop; - while(1) { - I32 c; - lex_read_space(0); - c = lex_peek_unichar(0); - switch(c) { - case /*(*/')': case /*{*/'}': { - OP *result = pop_rpn_item(); - if(stack) - croak("RPN expression must return " - "a single value"); - return result; - } break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - UV val = 0; - do { - lex_read_unichar(0); - val = 10*val + (c - '0'); - c = lex_peek_unichar(0); - } while(c >= '0' && c <= '9'); - push_rpn_item(newSVOP(OP_CONST, 0, - newSVuv(val))); - } break; - case '$': { - push_rpn_item(parse_var()); - } break; - case '+': { - OP *b = pop_rpn_item(); - OP *a = pop_rpn_item(); - lex_read_unichar(0); - push_rpn_item(newBINOP(OP_I_ADD, 0, a, b)); - } break; - case '-': { - OP *b = pop_rpn_item(); - OP *a = pop_rpn_item(); - lex_read_unichar(0); - push_rpn_item(newBINOP(OP_I_SUBTRACT, 0, a, b)); - } break; - case '*': { - OP *b = pop_rpn_item(); - OP *a = pop_rpn_item(); - lex_read_unichar(0); - push_rpn_item(newBINOP(OP_I_MULTIPLY, 0, a, b)); - } break; - case '/': { - OP *b = pop_rpn_item(); - OP *a = pop_rpn_item(); - lex_read_unichar(0); - push_rpn_item(newBINOP(OP_I_DIVIDE, 0, a, b)); - } break; - case '%': { - OP *b = pop_rpn_item(); - OP *a = pop_rpn_item(); - lex_read_unichar(0); - push_rpn_item(newBINOP(OP_I_MODULO, 0, a, b)); - } break; - default: { - croak("RPN syntax error"); - } break; - } - } -} -#define parse_rpn_expr() THX_parse_rpn_expr(aTHX) - -static OP *THX_parse_keyword_rpn(pTHX) -{ - OP *op; - lex_read_space(0); - if(lex_peek_unichar(0) != '('/*)*/) - croak("RPN expression must be parenthesised"); - lex_read_unichar(0); - op = parse_rpn_expr(); - if(lex_peek_unichar(0) != /*(*/')') - croak("RPN expression must be parenthesised"); - lex_read_unichar(0); - return op; -} -#define parse_keyword_rpn() THX_parse_keyword_rpn(aTHX) - -static OP *THX_parse_keyword_calcrpn(pTHX) -{ - OP *varop, *exprop; - lex_read_space(0); - varop = parse_var(); - lex_read_space(0); - if(lex_peek_unichar(0) != '{'/*}*/) - croak("RPN expression must be braced"); - lex_read_unichar(0); - exprop = parse_rpn_expr(); - if(lex_peek_unichar(0) != /*{*/'}') - croak("RPN expression must be braced"); - lex_read_unichar(0); - return newASSIGNOP(OPf_STACKED, varop, 0, exprop); -} -#define parse_keyword_calcrpn() THX_parse_keyword_calcrpn(aTHX) - -static OP *THX_parse_keyword_stufftest(pTHX) -{ - I32 c; - bool do_stuff; - lex_read_space(0); - do_stuff = lex_peek_unichar(0) == '+'; - if(do_stuff) { - lex_read_unichar(0); - lex_read_space(0); - } - c = lex_peek_unichar(0); - if(c == ';') { - lex_read_unichar(0); - } else if(c != /*{*/'}') { - croak("syntax error"); - } - if(do_stuff) lex_stuff_pvs(" ", 0); - return newOP(OP_NULL, 0); -} -#define parse_keyword_stufftest() THX_parse_keyword_stufftest(aTHX) - -static OP *THX_parse_keyword_swaptwostmts(pTHX) -{ - OP *a, *b; - a = parse_fullstmt(0); - 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); -} -#define parse_keyword_swaptwostmts() THX_parse_keyword_swaptwostmts(aTHX) - -/* plugin glue */ - -static int THX_keyword_active(pTHX_ SV *hintkey_sv) -{ - HE *he; - if(!GvHV(PL_hintgv)) return 0; - he = hv_fetch_ent(GvHV(PL_hintgv), hintkey_sv, 0, - SvSHARED_HASH(hintkey_sv)); - return he && SvTRUE(HeVAL(he)); -} -#define keyword_active(hintkey_sv) THX_keyword_active(aTHX_ hintkey_sv) - -static void THX_keyword_enable(pTHX_ SV *hintkey_sv) -{ - SV *val_sv = newSViv(1); - HE *he; - PL_hints |= HINT_LOCALIZE_HH; - gv_HVadd(PL_hintgv); - he = hv_store_ent(GvHV(PL_hintgv), - hintkey_sv, val_sv, SvSHARED_HASH(hintkey_sv)); - if(he) { - SV *val = HeVAL(he); - SvSETMAGIC(val); - } else { - SvREFCNT_dec(val_sv); - } -} -#define keyword_enable(hintkey_sv) THX_keyword_enable(aTHX_ hintkey_sv) - -static void THX_keyword_disable(pTHX_ SV *hintkey_sv) -{ - if(GvHV(PL_hintgv)) { - PL_hints |= HINT_LOCALIZE_HH; - hv_delete_ent(GvHV(PL_hintgv), - hintkey_sv, G_DISCARD, SvSHARED_HASH(hintkey_sv)); - } -} -#define keyword_disable(hintkey_sv) THX_keyword_disable(aTHX_ hintkey_sv) - -static int my_keyword_plugin(pTHX_ - char *keyword_ptr, STRLEN keyword_len, OP **op_ptr) -{ - if(keyword_len == 3 && strnEQ(keyword_ptr, "rpn", 3) && - keyword_active(hintkey_rpn_sv)) { - *op_ptr = parse_keyword_rpn(); - return KEYWORD_PLUGIN_EXPR; - } else if(keyword_len == 7 && strnEQ(keyword_ptr, "calcrpn", 7) && - keyword_active(hintkey_calcrpn_sv)) { - *op_ptr = parse_keyword_calcrpn(); - return KEYWORD_PLUGIN_STMT; - } else if(keyword_len == 9 && strnEQ(keyword_ptr, "stufftest", 9) && - keyword_active(hintkey_stufftest_sv)) { - *op_ptr = parse_keyword_stufftest(); - return KEYWORD_PLUGIN_STMT; - } else if(keyword_len == 12 && - strnEQ(keyword_ptr, "swaptwostmts", 12) && - keyword_active(hintkey_swaptwostmts_sv)) { - *op_ptr = parse_keyword_swaptwostmts(); - return KEYWORD_PLUGIN_STMT; - } else { - return next_keyword_plugin(aTHX_ - keyword_ptr, keyword_len, op_ptr); - } -} - -MODULE = XS::APItest::KeywordRPN PACKAGE = XS::APItest::KeywordRPN - -BOOT: - hintkey_rpn_sv = newSVpvs_share("XS::APItest::KeywordRPN/rpn"); - hintkey_calcrpn_sv = newSVpvs_share("XS::APItest::KeywordRPN/calcrpn"); - hintkey_stufftest_sv = - newSVpvs_share("XS::APItest::KeywordRPN/stufftest"); - hintkey_swaptwostmts_sv = - newSVpvs_share("XS::APItest::KeywordRPN/swaptwostmts"); - next_keyword_plugin = PL_keyword_plugin; - PL_keyword_plugin = my_keyword_plugin; - -void -import(SV *classname, ...) -PREINIT: - int i; -PPCODE: - for(i = 1; i != items; i++) { - SV *item = ST(i); - if(sv_is_string(item) && strEQ(SvPVX(item), "rpn")) { - keyword_enable(hintkey_rpn_sv); - } else if(sv_is_string(item) && strEQ(SvPVX(item), "calcrpn")) { - keyword_enable(hintkey_calcrpn_sv); - } else if(sv_is_string(item) && - strEQ(SvPVX(item), "stufftest")) { - keyword_enable(hintkey_stufftest_sv); - } else if(sv_is_string(item) && - strEQ(SvPVX(item), "swaptwostmts")) { - keyword_enable(hintkey_swaptwostmts_sv); - } else { - croak("\"%s\" is not exported by the %s module", - SvPV_nolen(item), SvPV_nolen(ST(0))); - } - } - -void -unimport(SV *classname, ...) -PREINIT: - int i; -PPCODE: - for(i = 1; i != items; i++) { - SV *item = ST(i); - if(sv_is_string(item) && strEQ(SvPVX(item), "rpn")) { - keyword_disable(hintkey_rpn_sv); - } else if(sv_is_string(item) && strEQ(SvPVX(item), "calcrpn")) { - keyword_disable(hintkey_calcrpn_sv); - } else if(sv_is_string(item) && - strEQ(SvPVX(item), "stufftest")) { - keyword_disable(hintkey_stufftest_sv); - } else if(sv_is_string(item) && - strEQ(SvPVX(item), "swaptwostmts")) { - keyword_disable(hintkey_swaptwostmts_sv); - } else { - croak("\"%s\" is not exported by the %s module", - SvPV_nolen(item), SvPV_nolen(ST(0))); - } - } diff --git a/ext/XS-APItest-KeywordRPN/Makefile.PL b/ext/XS-APItest-KeywordRPN/Makefile.PL deleted file mode 100644 index ae2c72a40c..0000000000 --- a/ext/XS-APItest-KeywordRPN/Makefile.PL +++ /dev/null @@ -1,17 +0,0 @@ -{ use 5.006; } -use warnings; -use strict; - -use ExtUtils::MakeMaker; - -WriteMakefile( - NAME => "XS::APItest::KeywordRPN", - VERSION_FROM => "KeywordRPN.pm", - PREREQ_PM => {}, - ABSTRACT_FROM => "KeywordRPN.pm", - AUTHOR => "Andrew Main (Zefram) <zefram\@fysh.org>", -); - -sub MY::install { "install ::\n" } - -1; diff --git a/ext/XS-APItest-KeywordRPN/README b/ext/XS-APItest-KeywordRPN/README deleted file mode 100644 index 4caa629af1..0000000000 --- a/ext/XS-APItest-KeywordRPN/README +++ /dev/null @@ -1,25 +0,0 @@ -NAME - -XS::APItest::KeywordRPN - write arithmetic expressions in RPN - -DESCRIPTION - -This module supplies plugged-in keywords, using the new mechanism in Perl -5.11.2, that allow arithmetic to be expressed in reverse Polish notation, -in an otherwise Perl program. This module has serious limitations and -is not intended for real use: its purpose is only to test the keyword -plugin mechanism. For that purpose it is part of the Perl core source -distribution, and is not meant to be installed. - -AUTHOR - -Andrew Main (Zefram) <zefram@fysh.org> - -COPYRIGHT - -Copyright (C) 2009 Andrew Main (Zefram) <zefram@fysh.org> - -LICENSE - -This module is free software; you can redistribute it and/or modify it -under the same terms as Perl itself. diff --git a/ext/XS-APItest-KeywordRPN/t/keyword_plugin.t b/ext/XS-APItest-KeywordRPN/t/keyword_plugin.t deleted file mode 100644 index 85f4b603a3..0000000000 --- a/ext/XS-APItest-KeywordRPN/t/keyword_plugin.t +++ /dev/null @@ -1,76 +0,0 @@ -use warnings; -use strict; - -use Test::More tests => 13; - -BEGIN { $^H |= 0x20000; } -no warnings; - -my($triangle, $num); -$num = 5; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN (); - $triangle = rpn($num $num 1 + * 2 /); -}; -isnt $@, ""; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(rpn); - $triangle = rpn($num $num 1 + * 2 /); -}; -is $@, ""; -is $triangle, 15; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(rpn); - $triangle = join(":", "x", rpn($num $num 1 + * 2 /), "y"); -}; -is $@, ""; -is $triangle, "x:15:y"; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(rpn); - $triangle = 1 + rpn($num $num 1 + * 2 /) * 10; -}; -is $@, ""; -is $triangle, 151; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(rpn); - $triangle = rpn($num $num 1 + * 2 /); - $triangle++; -}; -is $@, ""; -is $triangle, 16; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(rpn); - $triangle = rpn($num $num 1 + * 2 /) - $triangle++; -}; -isnt $@, ""; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(calcrpn); - calcrpn $triangle { $num $num 1 + * 2 / } - $triangle++; -}; -is $@, ""; -is $triangle, 16; - -$triangle = undef; -eval q{ - use XS::APItest::KeywordRPN qw(calcrpn); - 123 + calcrpn $triangle { $num $num 1 + * 2 / } ; -}; -isnt $@, ""; - -1; diff --git a/ext/XS-APItest-KeywordRPN/t/multiline.t b/ext/XS-APItest-KeywordRPN/t/multiline.t deleted file mode 100644 index b5c9c83063..0000000000 --- a/ext/XS-APItest-KeywordRPN/t/multiline.t +++ /dev/null @@ -1,27 +0,0 @@ -use warnings; -use strict; - -use Test::More tests => 4; - -my($t, $n); -$n = 5; - -use XS::APItest::KeywordRPN qw(rpn); -$t = rpn($n - $n 1 + - * #wibble -#wobble -2 - / -); -is $t, 15; -is __LINE__, 18; - -$t = 0; -$t = rpn($n $n 1 + * -#line 100 - 2 /); -is $t, 15; -is __LINE__, 102; - -1; diff --git a/ext/XS-APItest-KeywordRPN/t/stuff_svcur_bug.t b/ext/XS-APItest-KeywordRPN/t/stuff_svcur_bug.t deleted file mode 100644 index 4fd6e1151b..0000000000 --- a/ext/XS-APItest-KeywordRPN/t/stuff_svcur_bug.t +++ /dev/null @@ -1,12 +0,0 @@ -use warnings; -use strict; - -use Test::More tests => 1; -ok 1; - -use XS::APItest::KeywordRPN qw(stufftest); - -# In the buggy case, a syntax error occurs at EOF. -# Adding a semicolon, any following statements, or anything else -# causes the bug not to show itself. -stufftest+;() diff --git a/ext/XS-APItest-KeywordRPN/t/swaptwostmts.t b/ext/XS-APItest-KeywordRPN/t/swaptwostmts.t deleted file mode 100644 index 44e9e7aaae..0000000000 --- a/ext/XS-APItest-KeywordRPN/t/swaptwostmts.t +++ /dev/null @@ -1,158 +0,0 @@ -use warnings; -use strict; - -use Test::More tests => 22; - -BEGIN { $^H |= 0x20000; } - -my $t; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN (); - $t .= "a"; - swaptwostmts - $t .= "b"; - $t .= "c"; - $t .= "d"; -}; -isnt $@, ""; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b"; - $t .= "c"; - $t .= "d"; -}; -is $@, ""; -is $t, "acbd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - if(1) { $t .= "b"; } - $t .= "c"; - $t .= "d"; -}; -is $@, ""; -is $t, "acbd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b"; - if(1) { $t .= "c"; } - $t .= "d"; -}; -is $@, ""; -is $t, "acbd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b"; - foreach(1..3) { - $t .= "c"; - swaptwostmts - $t .= "d"; - $t .= "e"; - $t .= "f"; - } - $t .= "g"; -}; -is $@, ""; -is $t, "acedfcedfcedfbg"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b"; - $t .= "c"; -}; -is $@, ""; -is $t, "acb"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b"; - $t .= "c" -}; -is $@, ""; -is $t, "acb"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $t .= "a"; - swaptwostmts - $t .= "b" -}; -isnt $@, ""; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - $_ = $t; - $_ .= "a"; - swaptwostmts - if(1) { $_ .= "b"; } - tr/a-z/A-Z/; - $_ .= "d"; - $t = $_; -}; -is $@, ""; -is $t, "Abd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - sub add_to_t { $t .= $_[0]; } - add_to_t "a"; - swaptwostmts - if(1) { add_to_t "b"; } - add_to_t "c"; - add_to_t "d"; -}; -is $@, ""; -is $t, "acbd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - { $t .= "a"; } - swaptwostmts - if(1) { { $t .= "b"; } } - { $t .= "c"; } - { $t .= "d"; } -}; -is $@, ""; -is $t, "acbd"; - -$t = ""; -eval q{ - use XS::APItest::KeywordRPN qw(swaptwostmts); - no warnings "void"; - "@{[ $t .= 'a' ]}"; - swaptwostmts - if(1) { "@{[ $t .= 'b' ]}"; } - "@{[ $t .= 'c' ]}"; - "@{[ $t .= 'd' ]}"; -}; -is $@, ""; -is $t, "acbd"; - -1; |