New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
KEYWORD_PLUGIN_NOOP for keyword plugins #12224
Comments
From @maukeCreated by @maukeThere should be a way for keyword plugins to indicate that a keyword was Currently all keyword plugins have to pretend to be an expression I propose adding KEYWORD_PLUGIN_NOOP. It indicates that the keyword was Perl Info
|
From @maukeOn 2012-06-25 l.mai@web.de (via RT) wrote:
Patch attached. It implements KEYWORD_PLUGIN_NOOP, adds a paragraph to Thoughts? |
From @mauke0001-add-KEYWORD_PLUGIN_NOOP-for-keyword-plugins.patchFrom 72d2d3ff7b3302ff5580fd6f0c76d78fe4c58a29 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Mon, 25 Jun 2012 22:01:54 +0200
Subject: [PATCH] add KEYWORD_PLUGIN_NOOP for keyword plugins
---
ext/XS-APItest/APItest.pm | 4 ++--
ext/XS-APItest/APItest.xs | 37 +++++++++++++++++++++++++++++++++++++
ext/XS-APItest/t/dollarx.t | 19 +++++++++++++++++++
ext/XS-APItest/t/noop.t | 21 +++++++++++++++++++++
ext/XS-APItest/t/swallowtill.t | 31 +++++++++++++++++++++++++++++++
perl.h | 1 +
perlvars.h | 4 ++++
toke.c | 3 +++
8 files changed, 118 insertions(+), 2 deletions(-)
create mode 100644 ext/XS-APItest/t/dollarx.t
create mode 100644 ext/XS-APItest/t/noop.t
create mode 100644 ext/XS-APItest/t/swallowtill.t
diff --git a/ext/XS-APItest/APItest.pm b/ext/XS-APItest/APItest.pm
index 0eff22e..da3cae8 100644
--- a/ext/XS-APItest/APItest.pm
+++ b/ext/XS-APItest/APItest.pm
@@ -5,7 +5,7 @@ use strict;
use warnings;
use Carp;
-our $VERSION = '0.40';
+our $VERSION = '0.41';
require XSLoader;
@@ -40,7 +40,7 @@ sub import {
}
}
foreach (keys %{$exports||{}}) {
- next unless /\A(?:rpn|calcrpn|stufftest|swaptwostmts|looprest|scopelessblock|stmtasexpr|stmtsasexpr|loopblock|blockasexpr|swaplabel|labelconst|arrayfullexpr|arraylistexpr|arraytermexpr|arrayarithexpr|arrayexprflags)\z/;
+ next unless /\A(?:rpn|calcrpn|stufftest|swaptwostmts|looprest|scopelessblock|stmtasexpr|stmtsasexpr|loopblock|blockasexpr|swaplabel|labelconst|arrayfullexpr|arraylistexpr|arraytermexpr|arrayarithexpr|arrayexprflags|noop|dollarx|swallowtill)\z/;
$^H{"XS::APItest/$_"} = 1;
delete $exports->{$_};
}
diff --git a/ext/XS-APItest/APItest.xs b/ext/XS-APItest/APItest.xs
index 69b7066..f446c3a 100644
--- a/ext/XS-APItest/APItest.xs
+++ b/ext/XS-APItest/APItest.xs
@@ -656,6 +656,9 @@ static SV *hintkey_swaplabel_sv, *hintkey_labelconst_sv;
static SV *hintkey_arrayfullexpr_sv, *hintkey_arraylistexpr_sv;
static SV *hintkey_arraytermexpr_sv, *hintkey_arrayarithexpr_sv;
static SV *hintkey_arrayexprflags_sv;
+static SV *hintkey_noop_sv;
+static SV *hintkey_dollarx_sv;
+static SV *hintkey_swallowtill_sv;
static int (*next_keyword_plugin)(pTHX_ char *, STRLEN, OP **);
/* low-level parser helpers */
@@ -941,6 +944,26 @@ static OP *THX_parse_keyword_arrayexprflags(pTHX)
return o ? newANONLIST(o) : newANONHASH(newOP(OP_STUB, 0));
}
+#define parse_keyword_dollarx() THX_parse_keyword_dollarx(aTHX)
+static void THX_parse_keyword_dollarx(pTHX)
+{
+ lex_stuff_pvs("$x", 0);
+}
+
+#define parse_keyword_swallowtill() THX_parse_keyword_swallowtill(aTHX)
+static void THX_parse_keyword_swallowtill(pTHX)
+{
+ I32 c, d;
+ lex_read_space(0);
+ d = lex_read_unichar(0);
+ if (d == -1) croak("unexpected EOF");
+ do {
+ c = lex_read_unichar(0);
+ } while (c != -1 && c != d);
+ if (c == -1) croak("unexpected EOF while looking for %ld ('%c')", (long)d, (char)d);
+ lex_read_space(0);
+}
+
/* plugin glue */
#define keyword_active(hintkey_sv) THX_keyword_active(aTHX_ hintkey_sv)
@@ -1025,6 +1048,17 @@ static int my_keyword_plugin(pTHX_
keyword_active(hintkey_arrayexprflags_sv)) {
*op_ptr = parse_keyword_arrayexprflags();
return KEYWORD_PLUGIN_EXPR;
+ } else if(keyword_len == 4 && strnEQ(keyword_ptr, "noop", 4) &&
+ keyword_active(hintkey_noop_sv)) {
+ return KEYWORD_PLUGIN_NOOP;
+ } else if(keyword_len == 7 && strnEQ(keyword_ptr, "dollarx", 7) &&
+ keyword_active(hintkey_dollarx_sv)) {
+ parse_keyword_dollarx();
+ return KEYWORD_PLUGIN_NOOP;
+ } else if(keyword_len == 11 && strnEQ(keyword_ptr, "swallowtill", 11) &&
+ keyword_active(hintkey_swallowtill_sv)) {
+ parse_keyword_swallowtill();
+ return KEYWORD_PLUGIN_NOOP;
} else {
return next_keyword_plugin(aTHX_ keyword_ptr, keyword_len, op_ptr);
}
@@ -3174,6 +3208,9 @@ BOOT:
hintkey_arraytermexpr_sv = newSVpvs_share("XS::APItest/arraytermexpr");
hintkey_arrayarithexpr_sv = newSVpvs_share("XS::APItest/arrayarithexpr");
hintkey_arrayexprflags_sv = newSVpvs_share("XS::APItest/arrayexprflags");
+ hintkey_noop_sv = newSVpvs_share("XS::APItest/noop");
+ hintkey_dollarx_sv = newSVpvs_share("XS::APItest/dollarx");
+ hintkey_swallowtill_sv = newSVpvs_share("XS::APItest/swallowtill");
next_keyword_plugin = PL_keyword_plugin;
PL_keyword_plugin = my_keyword_plugin;
}
diff --git a/ext/XS-APItest/t/dollarx.t b/ext/XS-APItest/t/dollarx.t
new file mode 100644
index 0000000..34da05a
--- /dev/null
+++ b/ext/XS-APItest/t/dollarx.t
@@ -0,0 +1,19 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $x;
+
+$x = "";
+eval q{
+ use XS::APItest qw(dollarx);
+ $x .= "a";
+ dollarx .= "b";
+ dollarx .= dollarx;
+ $x .= "c";
+};
+is $@, "";
+is $x, "ababc";
diff --git a/ext/XS-APItest/t/noop.t b/ext/XS-APItest/t/noop.t
new file mode 100644
index 0000000..3fc1268
--- /dev/null
+++ b/ext/XS-APItest/t/noop.t
@@ -0,0 +1,21 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $t;
+
+$t = "";
+eval q{
+ use XS::APItest qw(noop);
+ $t .= "a";
+ noop $t .= "b";
+ $t noop .= "c";
+ $t .= noop "d";
+ $t .= "e" noop;
+ $t .= "f"; noop
+};
+is $@, "";
+is $t, "abcdef";
diff --git a/ext/XS-APItest/t/swallowtill.t b/ext/XS-APItest/t/swallowtill.t
new file mode 100644
index 0000000..4bf7e5f
--- /dev/null
+++ b/ext/XS-APItest/t/swallowtill.t
@@ -0,0 +1,31 @@
+use warnings;
+use strict;
+
+use Test::More tests => 2;
+
+BEGIN { $^H |= 0x20000; }
+
+my $t;
+
+$t = "";
+eval q{
+ use XS::APItest qw(swallowtill);
+ $t .= "a";
+ swallowtill;
+ $t .= "A";
+ $t .= "b";
+ swallowtill
+ ~
+ $t .= "B";
+ ~$t .= "c";
+ $t swallowtill.= "C";..= "d";
+ $t .= swallowtill s // s "e";
+ $t .= "f" swallowtill- #- ;
+ swallowtill**
+ $t swallowtill \ .= "D";
+ $t .= "E";
+ \ .= # "F";
+ swallowtill"G""g";
+};
+is $@, "";
+is $t, "abcdefg";
diff --git a/perl.h b/perl.h
index 2fec311..1999303 100644
--- a/perl.h
+++ b/perl.h
@@ -4923,6 +4923,7 @@ typedef void(*globhook_t)(pTHX);
#define KEYWORD_PLUGIN_DECLINE 0
#define KEYWORD_PLUGIN_STMT 1
#define KEYWORD_PLUGIN_EXPR 2
+#define KEYWORD_PLUGIN_NOOP 3
/* Interpreter exitlist entry */
typedef struct exitlistentry {
diff --git a/perlvars.h b/perlvars.h
index 20c3882..272b20e 100644
--- a/perlvars.h
+++ b/perlvars.h
@@ -201,6 +201,10 @@ it does not wish to generate any ops to be included in the normal
compilation. In this case it is still required to supply an op tree,
but it suffices to generate a single null op.
+The function can also return C<KEYWORD_PLUGIN_NOOP> to indicate that it handled
+the keyword all by itself and didn't build an C<OP> tree. Perl will proceed to
+parse the input as if the keyword hadn't been there in the first place.
+
That's how the C<*PL_keyword_plugin> function needs to behave overall.
Conventionally, however, one does not completely replace the existing
handler function. Instead, take a copy of C<PL_keyword_plugin> before
diff --git a/toke.c b/toke.c
index df73b88..5a80a8b 100644
--- a/toke.c
+++ b/toke.c
@@ -6596,6 +6596,9 @@ Perl_yylex(pTHX)
CLINE;
PL_expect = XOPERATOR;
return REPORT(PLUGEXPR);
+ } else if (result == KEYWORD_PLUGIN_NOOP) {
+ /* pretend we didn't see anything */
+ goto retry;
} else {
Perl_croak(aTHX_ "Bad plugin affecting keyword '%s'",
PL_tokenbuf);
--
1.7.8.5
|
From zefram@fysh.orgl.mai@web.de wrote:
You can still inject source from a keyword plugin, and then call
Aside from being unnecessary, that's a messy interface. Devel::Declare -zefram |
The RT System itself - Status changed from 'new' to 'open' |
From @maukeOn 2012-06-26 Zefram via RT wrote:
That assumes 1) the generated code represents a statement or expression use Macro MYOPERATOR => '+'; or use Comment 'NB'; I'm not saying these are necessarily good ideas but they show that the Another issue is that even if 1) and 2) are true, parse_fullexpr() may Without it you would first have to look ahead in the buffer to see If an identifier follows, you inject "sub", call parse_stmt(), and print After injection: print If you call parse_fullexpr now, you end up with print $x * <<expr>>; This is completely wrong. With parse_listexpr you get print Still wrong. With parse_termexpr you get print Still wrong. With parse_arithexpr you get the same result as with
The point of the examples above was to show that it isn't unnecessary (And honestly, after having used the native OP * functions, "that's a
IMHO this sort of local source code munging is still the easiest way to Lukas |
From @jkeenanThis feature request has failed to receive a second in the twelve months I recommend that this ticket be closed unless someone wishes to submit a I am taking this ticket for the purpose of closing it within 7 days Thank you very much. |
From @maukeOn 17.06.2013 03:28, James E Keenan via RT wrote:
Huh? A patch for what? I attached a patch to my first reply. What else (And I still want to see this go into the core.) -- |
From @jkeenanOn Sun Jun 16 20:55:35 2013, plokinom@gmail.com wrote:
I'm sorry, I overlooked that.
Nonetheless, no one has spoken up in support of either the feature Thank you very much. |
From @cpansproutOn Mon Jun 17 03:44:20 2013, jkeenan wrote:
It seems like a logical patch to me. But Zefram was opposed to it (he I know Zefram wanted to deprecate the keyword plugin mechanism in favour So I would like to see this patch go in, but I don’t think I have the -- Father Chrysostomos |
From @maukeOn 17.06.2013 15:32, Father Chrysostomos via RT wrote:
By the way, I have a module that would really benefit from this feature. But with KEYWORD_PLUGIN_NOOP I think it could immediately do everything -- |
Migrated from rt.perl.org#113836 (status was 'open')
Searchable as RT113836$
The text was updated successfully, but these errors were encountered: