Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package perl-XS-Parse-Keyword for
openSUSE:Factory checked in at 2022-11-09 12:56:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword (Old)
and /work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1597 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-XS-Parse-Keyword"
Wed Nov 9 12:56:30 2022 rev:9 rq:1034531 version:0.27
Changes:
--------
---
/work/SRC/openSUSE:Factory/perl-XS-Parse-Keyword/perl-XS-Parse-Keyword.changes
2022-08-17 18:23:04.175168450 +0200
+++
/work/SRC/openSUSE:Factory/.perl-XS-Parse-Keyword.new.1597/perl-XS-Parse-Keyword.changes
2022-11-09 12:56:40.200089005 +0100
@@ -1,0 +2,24 @@
+Tue Nov 1 03:08:08 UTC 2022 - Tina M??ller <[email protected]>
+
+- updated to 0.27
+ see /usr/share/doc/packages/perl-XS-Parse-Keyword/Changes
+
+ 0.27 2022-10-31
+ [CHANGES]
+ * Updates to XS::Parse::Infix for latest `infix-plugin` perl5 branch
+ + parsedata field is now an SV **, not an ANY *
+ * Expose parse_infix() as a real ABI function, allowing infix
+ operators to be hyper-operators and parse other operator names
+
+ 0.26 2022-10-24
+ [CHANGES]
+ * Updates to XS::Parse::Infix for latest `infix-plugin` perl5 branch
+ + Requires classification to set the operator precedence
+ + No longer need XPI_OPERAND_ARITH or XPI_OPERAND_TERM; most of
+ .lhs_flags and .rhs_flags are redundant now
+ + No longer support XPI_OPERAND_CUSTOM
+ + Optional `parse` phase for parametric/hyper-operators
+ * Bump XS::Parse::Infix ABI version to 2
+ * Declare XPI ABI v0 as deprecated, soon to be removed
+
+-------------------------------------------------------------------
Old:
----
XS-Parse-Keyword-0.25.tar.gz
New:
----
XS-Parse-Keyword-0.27.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-XS-Parse-Keyword.spec ++++++
--- /var/tmp/diff_new_pack.S8cUwP/_old 2022-11-09 12:56:40.784092297 +0100
+++ /var/tmp/diff_new_pack.S8cUwP/_new 2022-11-09 12:56:40.788092320 +0100
@@ -18,7 +18,7 @@
%define cpan_name XS-Parse-Keyword
Name: perl-XS-Parse-Keyword
-Version: 0.25
+Version: 0.27
Release: 0
License: Artistic-1.0 OR GPL-1.0-or-later
Summary: XS functions to assist in parsing keyword syntax
++++++ XS-Parse-Keyword-0.25.tar.gz -> XS-Parse-Keyword-0.27.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/Build.PL
new/XS-Parse-Keyword-0.27/Build.PL
--- old/XS-Parse-Keyword-0.25/Build.PL 2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/Build.PL 2022-10-31 23:09:16.000000000 +0100
@@ -54,7 +54,12 @@
#include "perl.h"
#include "XSUB.h"
-int main(void) { struct Perl_custom_infix def; return 0; }
+int main(void) {
+ struct Perl_custom_infix def;
+ def.prec = INFIX_PREC_LOW;
+ def.build_op = NULL;
+ return 0;
+}
EOF
) if $] >= 5.037000; # maybe I'll start this in 5.37...
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/Changes
new/XS-Parse-Keyword-0.27/Changes
--- old/XS-Parse-Keyword-0.25/Changes 2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/Changes 2022-10-31 23:09:16.000000000 +0100
@@ -1,5 +1,23 @@
Revision history for XS-Parse-Keyword
+0.27 2022-10-31
+ [CHANGES]
+ * Updates to XS::Parse::Infix for latest `infix-plugin` perl5 branch
+ + parsedata field is now an SV **, not an ANY *
+ * Expose parse_infix() as a real ABI function, allowing infix
+ operators to be hyper-operators and parse other operator names
+
+0.26 2022-10-24
+ [CHANGES]
+ * Updates to XS::Parse::Infix for latest `infix-plugin` perl5 branch
+ + Requires classification to set the operator precedence
+ + No longer need XPI_OPERAND_ARITH or XPI_OPERAND_TERM; most of
+ .lhs_flags and .rhs_flags are redundant now
+ + No longer support XPI_OPERAND_CUSTOM
+ + Optional `parse` phase for parametric/hyper-operators
+ * Bump XS::Parse::Infix ABI version to 2
+ * Declare XPI ABI v0 as deprecated, soon to be removed
+
0.25 2022-07-25
[CHANGES]
* Permit infix operators to consume fewer than all the available
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/MANIFEST
new/XS-Parse-Keyword-0.27/MANIFEST
--- old/XS-Parse-Keyword-0.25/MANIFEST 2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/MANIFEST 2022-10-31 23:09:16.000000000 +0100
@@ -6,6 +6,7 @@
hax/make_argcheck_ops.c.inc
hax/newOP_CUSTOM.c.inc
hax/op_sibling_splice.c.inc
+hax/optree-additions.c.inc
hax/perl-backcompat.c.inc
hax/wrap_keyword_plugin.c.inc
inc/Module/Build/with/XSTests.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/META.json
new/XS-Parse-Keyword-0.27/META.json
--- old/XS-Parse-Keyword-0.25/META.json 2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/META.json 2022-10-31 23:09:16.000000000 +0100
@@ -40,19 +40,19 @@
"provides" : {
"XS::Parse::Infix" : {
"file" : "lib/XS/Parse/Infix.pm",
- "version" : "0.25"
+ "version" : "0.27"
},
"XS::Parse::Infix::Builder" : {
"file" : "lib/XS/Parse/Infix/Builder.pm",
- "version" : "0.25"
+ "version" : "0.27"
},
"XS::Parse::Keyword" : {
"file" : "lib/XS/Parse/Keyword.pm",
- "version" : "0.25"
+ "version" : "0.27"
},
"XS::Parse::Keyword::Builder" : {
"file" : "lib/XS/Parse/Keyword/Builder.pm",
- "version" : "0.25"
+ "version" : "0.27"
}
},
"release_status" : "stable",
@@ -61,6 +61,6 @@
"http://dev.perl.org/licenses/"
]
},
- "version" : "0.25",
+ "version" : "0.27",
"x_serialization_backend" : "JSON::PP version 4.06"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/META.yml
new/XS-Parse-Keyword-0.27/META.yml
--- old/XS-Parse-Keyword-0.25/META.yml 2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/META.yml 2022-10-31 23:09:16.000000000 +0100
@@ -19,19 +19,19 @@
provides:
XS::Parse::Infix:
file: lib/XS/Parse/Infix.pm
- version: '0.25'
+ version: '0.27'
XS::Parse::Infix::Builder:
file: lib/XS/Parse/Infix/Builder.pm
- version: '0.25'
+ version: '0.27'
XS::Parse::Keyword:
file: lib/XS/Parse/Keyword.pm
- version: '0.25'
+ version: '0.27'
XS::Parse::Keyword::Builder:
file: lib/XS/Parse/Keyword/Builder.pm
- version: '0.25'
+ version: '0.27'
requires:
perl: '5.014'
resources:
license: http://dev.perl.org/licenses/
-version: '0.25'
+version: '0.27'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/XSParseInfix.h
new/XS-Parse-Keyword-0.27/XSParseInfix.h
--- old/XS-Parse-Keyword-0.25/XSParseInfix.h 2022-07-26 00:36:23.000000000
+0200
+++ new/XS-Parse-Keyword-0.27/XSParseInfix.h 2022-10-31 23:09:16.000000000
+0100
@@ -1,7 +1,7 @@
#ifndef __XS_PARSE_INFIX_H__
#define __XS_PARSE_INFIX_H__
-#define XSPARSEINFIX_ABI_VERSION 1
+#define XSPARSEINFIX_ABI_VERSION 2
/* Infix operator classifications */
/* No built-in operators use the _MISC categories, but they are provided for
@@ -16,6 +16,10 @@
XPI_CLS_ISA, /* ... the predicate instance of (isa) */
XPI_CLS_MATCH_MISC, /* ... any other match-like predicate */
XPI_CLS_ORDERING, /* cmp or <=> */
+
+ XPI_CLS_ADD_MISC, /* an operator at addition-like precedence */
+ XPI_CLS_MUL_MISC, /* an operator at multiplication-like precedence */
+ XPI_CLS_POW_MISC, /* an operator at power exponentiation-like precedence
*/
};
enum XSParseInfixSelection {
@@ -31,16 +35,16 @@
/* lhs_flags, rhs_flags */
enum {
- /* other space reserved for other scalar types */
- XPI_OPERAND_ARITH = 2,
- XPI_OPERAND_TERM = 4,
XPI_OPERAND_TERM_LIST = 6, /* term in list context */
XPI_OPERAND_LIST = 7, /* list in list context */
/* Other bitflags */
XPI_OPERAND_ONLY_LOOK = (1<<3),
- XPI_OPERAND_CUSTOM = (1<<7), /* rhs_flags only */
};
+// No longer used
+#define XPI_OPERAND_ARITH 0
+#define XPI_OPERAND_TERM 0
+#define XPI_OPERAND_CUSTOM (1<<7)
struct XSParseInfixHooks {
U16 flags;
@@ -54,11 +58,11 @@
bool (*permit) (pTHX_ void *hookdata);
/* These hooks are alternatives; the first one defined is used */
- OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
+ OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, SV **parsedata, void
*hookdata);
OP *(*ppaddr)(pTHX); /* A pp func used directly in newBINOP_custom() */
- /* Used if rhs_flags & XPI_OPERAND_CUSTOM */
- OP *(*parse_rhs)(pTHX_ void *hookdata);
+ /* optional */
+ void (*parse)(pTHX_ U32 flags, SV **parsedata, void *hookdata);
};
struct XSParseInfixInfo {
@@ -69,6 +73,18 @@
void *hookdata;
};
+static bool (*parse_infix_func)(pTHX_ enum XSParseInfixSelection select,
struct XSParseInfixInfo **infop);
+#define parse_infix(select, infop) S_parse_infix(aTHX_ select, infop)
+static bool S_parse_infix(pTHX_ enum XSParseInfixSelection select, struct
XSParseInfixInfo **infop)
+{
+ if(!parse_infix_func)
+ croak("Must call boot_xs_parse_infix() first");
+
+ struct XSParseInfixInfo *infocopy;
+
+ return (*parse_infix_func)(aTHX_ select, infop);
+}
+
static OP *(*xs_parse_infix_new_op_func)(pTHX_ const struct XSParseInfixInfo
*info, U32 flags, OP *lhs, OP *rhs);
#define xs_parse_infix_new_op(info, flags, lhs, rhs)
S_xs_parse_infix_new_op(aTHX_ info, flags, lhs, rhs)
static OP *S_xs_parse_infix_new_op(pTHX_ const struct XSParseInfixInfo *info,
U32 flags, OP *lhs, OP *rhs)
@@ -111,10 +127,12 @@
croak("XS::Parse::Infix ABI version mismatch - library supports <= %d,
compiled for %d",
abi_ver, XSPARSEINFIX_ABI_VERSION);
+ parse_infix_func = INT2PTR(bool (*)(pTHX_ enum XSParseInfixSelection, struct
XSParseInfixInfo **),
+ SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/parse()@2", 0)));
xs_parse_infix_new_op_func = INT2PTR(OP *(*)(pTHX_ const struct
XSParseInfixInfo *, U32, OP *, OP *),
SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/new_op()@0", 0)));
register_xs_parse_infix_func = INT2PTR(void (*)(pTHX_ const char *, const
struct XSParseInfixHooks *, void *),
- SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@1", 0)));
+ SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@2", 0)));
}
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/hax/optree-additions.c.inc
new/XS-Parse-Keyword-0.27/hax/optree-additions.c.inc
--- old/XS-Parse-Keyword-0.25/hax/optree-additions.c.inc 1970-01-01
01:00:00.000000000 +0100
+++ new/XS-Parse-Keyword-0.27/hax/optree-additions.c.inc 2022-10-31
23:09:16.000000000 +0100
@@ -0,0 +1,92 @@
+/* vi: set ft=c : */
+
+#define newAELEMOP(flags, first, key) S_newAELEMOP(aTHX_ flags, first, key)
+static OP *S_newAELEMOP(pTHX_ U32 flags, OP *first, I32 key)
+{
+#if HAVE_PERL_VERSION(5, 16, 0)
+ if(key >= -128 && key < 128 && first->op_type == OP_PADAV) {
+ OP *o = newOP(OP_AELEMFAST_LEX, flags);
+ o->op_private = (I8)key;
+ o->op_targ = first->op_targ;
+ op_free(first);
+ return o;
+ }
+#endif
+
+ return newBINOP(OP_AELEM, flags, first, newSVOP(OP_CONST, 0, newSViv(key)));
+}
+
+#define newPADxVOP(type, flags, padix) S_newPADxVOP(aTHX_ type, flags, padix)
+static OP *S_newPADxVOP(pTHX_ I32 type, I32 flags, PADOFFSET padix)
+{
+ OP *op = newOP(type, flags);
+ op->op_targ = padix;
+ return op;
+}
+
+#if HAVE_PERL_VERSION(5, 22, 0)
+# define HAVE_UNOP_AUX
+#endif
+
+#ifndef HAVE_UNOP_AUX
+typedef struct UNOP_with_IV {
+ UNOP baseop;
+ IV iv;
+} UNOP_with_IV;
+
+#define newUNOP_with_IV(type, flags, first, iv) S_newUNOP_with_IV(aTHX_ type,
flags, first, iv)
+static OP *S_newUNOP_with_IV(pTHX_ I32 type, I32 flags, OP *first, IV iv)
+{
+ /* Cargoculted from perl's op.c:Perl_newUNOP()
+ */
+ UNOP_with_IV *op = PerlMemShared_malloc(sizeof(UNOP_with_IV) * 1);
+ NewOp(1101, op, 1, UNOP_with_IV);
+
+ if(!first)
+ first = newOP(OP_STUB, 0);
+ UNOP *unop = (UNOP *)op;
+ unop->op_type = (OPCODE)type;
+ unop->op_first = first;
+ unop->op_ppaddr = NULL;
+ unop->op_flags = (U8)flags | OPf_KIDS;
+ unop->op_private = (U8)(1 | (flags >> 8));
+
+ op->iv = iv;
+
+ return (OP *)op;
+}
+#endif
+
+#define newMETHOD_REDIR_OP(rclass, methname, flags)
S_newMETHOD_REDIR_OP(aTHX_ rclass, methname, flags)
+static OP *S_newMETHOD_REDIR_OP(pTHX_ SV *rclass, SV *methname, I32 flags)
+{
+#if HAVE_PERL_VERSION(5, 22, 0)
+ OP *op = newMETHOP_named(OP_METHOD_REDIR, flags, methname);
+# ifdef USE_ITHREADS
+ {
+ /* cargoculted from S_op_relocate_sv() */
+ PADOFFSET ix = pad_alloc(OP_CONST, SVf_READONLY);
+ PAD_SETSV(ix, rclass);
+ cMETHOPx(op)->op_rclass_targ = ix;
+ }
+# else
+ cMETHOPx(op)->op_rclass_sv = rclass;
+# endif
+#else
+ OP *op = newUNOP(OP_METHOD, flags,
+ newSVOP(OP_CONST, 0, newSVpvf("%" SVf "::%" SVf, rclass, methname)));
+#endif
+
+ return op;
+}
+
+/* If `@_` is called "snail", then elements of it can be called "slugs"; i.e.
+ * snails without their container
+ */
+#define newSLUGOP(idx) S_newSLUGOP(aTHX_ idx)
+static OP *S_newSLUGOP(pTHX_ int idx)
+{
+ OP *op = newGVOP(OP_AELEMFAST, 0, PL_defgv);
+ op->op_private = idx;
+ return op;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/hax/perl-backcompat.c.inc
new/XS-Parse-Keyword-0.27/hax/perl-backcompat.c.inc
--- old/XS-Parse-Keyword-0.25/hax/perl-backcompat.c.inc 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/hax/perl-backcompat.c.inc 2022-10-31
23:09:16.000000000 +0100
@@ -34,6 +34,16 @@
#if !HAVE_PERL_VERSION(5, 22, 0)
# define CvPADLIST_set(cv, padlist) (CvPADLIST(cv) = padlist)
+# define newPADNAMEpvn(p,n) S_newPADNAMEpvn(aTHX_ p,n)
+static PADNAME *S_newPADNAMEpvn(pTHX_ const char *pv, STRLEN n)
+{
+ PADNAME *pn = newSVpvn(pv, n);
+ /* PADNAMEs need to be at least SVt_PVNV in order to store the COP_SEQ_*
+ * fields */
+ sv_upgrade(pn, SVt_PVNV);
+ return pn;
+}
+# define PadnameREFCNT_dec(pn) SvREFCNT_dec(pn)
#endif
#ifndef av_count
@@ -149,3 +159,32 @@
# define isIDFIRST_utf8_safe(s, e) (PERL_UNUSED_ARG(e), isIDFIRST_utf8(s))
# define isIDCONT_utf8_safe(s, e) (PERL_UNUSED_ARG(e), isIDCONT_utf8(s))
#endif
+
+#if !HAVE_PERL_VERSION(5, 26, 0)
+# define sv_set_undef(sv) sv_setsv(sv, &PL_sv_undef)
+#endif
+
+#ifndef newAVav
+# define newAVav(av) S_newAVav(aTHX_ av)
+static AV *S_newAVav(pTHX_ AV *av)
+{
+ AV *ret = newAV();
+ U32 count = av_count(av);
+ U32 i;
+ for(i = 0; i < count; i++)
+ av_push(ret, newSVsv(AvARRAY(av)[i]));
+ return ret;
+}
+#endif
+
+#if !defined(sv_derived_from_hv) && HAVE_PERL_VERSION(5, 16, 0)
+# define sv_derived_from_hv(sv, hv) MY_sv_derived_from_hv(aTHX_ sv, hv)
+static bool MY_sv_derived_from_hv(pTHX_ SV *sv, HV *hv)
+{
+ char *hvname = HvNAME(hv);
+ if(!hvname)
+ return FALSE;
+
+ return sv_derived_from_pvn(sv, hvname, HvNAMELEN(hv), HvNAMEUTF8(hv) ?
SVf_UTF8 : 0);
+}
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix/Builder.pm
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder.pm
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix/Builder.pm 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder.pm 2022-10-31
23:09:16.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021 -- [email protected]
-package XS::Parse::Infix::Builder 0.25;
+package XS::Parse::Infix::Builder 0.27;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix/Builder_data.pm.PL
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder_data.pm.PL
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix/Builder_data.pm.PL
2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix/Builder_data.pm.PL
2022-10-31 23:09:16.000000000 +0100
@@ -28,7 +28,7 @@
<$in_h> } );
__DATA__
-package XS::Parse::Infix::Builder_data 0.25;
+package XS::Parse::Infix::Builder_data 0.27;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix.pm
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix.pm
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Infix.pm 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Infix.pm 2022-10-31
23:09:16.000000000 +0100
@@ -1,9 +1,9 @@
# You may distribute under the terms of either the GNU General Public License
# or the Artistic License (the same terms as Perl itself)
#
-# (C) Paul Evans, 2021 -- [email protected]
+# (C) Paul Evans, 2021-2022 -- [email protected]
-package XS::Parse::Infix 0.25;
+package XS::Parse::Infix 0.27;
use v5.14;
use warnings;
@@ -68,6 +68,15 @@
boot_xs_parse_infix(0.14);
+=head2 parse_infix
+
+ bool parse_infix(enum XSParseInfixSelection select, struct XSParseInfixInfo
**infop);
+
+This function attempts to parse syntax for an infix operator from the current
+parser position. If it is successful, it fills in the variable pointed to by
+I<infop> with a pointer to the actual information structure and returns
+C<true>. If no suitable operator is found, returns C<false>.
+
=head2 xs_parse_infix_new_op
OP *xs_parse_infix_new_op(const struct XSParseInfixInfo *info, U32 flags,
@@ -79,7 +88,7 @@
The C<info> structure pointer would be obtained from the C<infix> field of the
result of invoking the various C<XPK_INFIX_*> token types from
-C<XS::Parse::Keyword>.
+C<XS::Parse::Keyword>, or by calling L</parse_infix> directly.
=head2 register_xs_parse_infix
@@ -88,8 +97,8 @@
This function installs a set of parsing hooks to be associated with the given
operator name. This new operator will then be available via
-L<XS::Parse::Keyword> by the various C<XPK_INFIX_*> token types, or to core
-perl's C<PL_infix_plugin> if availble.
+L<XS::Parse::Keyword> by the various C<XPK_INFIX_*> token types,
+L</parse_infix>, or to core perl's C<PL_infix_plugin> if available.
These tokens will all yield an info structure, with the following fields:
@@ -123,8 +132,11 @@
const char *permit_hintkey;
bool (*permit)(pTHX_ void *hookdata);
- OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
+ OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, ANY *parsedata, void
*hookdata);
OP *(*ppaddr)(pTHX);
+
+ /* optional */
+ void (*parse)(pTHX_ U32 flags, ANY *parsedata, void *hookdata);
};
=head2 Flags
@@ -132,32 +144,30 @@
The C<flags> field is currently ignored. It is defined simply to reserve the
space in case used in a later version. It should be set to zero.
-The C<rhs_flags> field gives details on how to parse and handle the right-hand
-side of the operator syntax. It should be set to one of the following
constants:
+The C<lhs_flags> and C<rhs_flags> fields give details on how to handle the
+left- and right-hand side operands, respectively.
-=over 4
+It should be set to one of the following constants, or left as zero:
-=item XPI_OPERAND_ARITH
-
-The operand is an arithmetic expression.
-
-=item XPI_OPERAND_TERM
-
-The operand is a term expression.
+=over 4
=item XPI_OPERAND_TERM_LIST
-The operand is a term expression. It will be foced into list context,
-preserving the C<OP_PUSHMARK> at the beginning. This means that the ppfunc for
-this infix operator will have to C<POPMARK> to find that.
+The operand will be foced into list context, preserving the C<OP_PUSHMARK> at
+the beginning. This means that the ppfunc for this infix operator will have to
+C<POPMARK> to find that.
=item XPI_OPERAND_LIST
-The operand is a list expression. It will be forced into list context, the
-same as above.
+The same as above.
=back
+Older versions used to provide constants named C<XPI_OPERAND_ARITH> and
+C<XPI_OPERAND_TERM> but they related to an older version of the core perl
+branch. These names are now aliases for zero, and can be removed from new
+code.
+
In addition the following extra bitflags are defined:
=over 4
@@ -183,12 +193,6 @@
=back
-The C<lhs_flags> field gives details on how to handle the left-hand side of
-the operator syntax. It takes similar values to C<rhs_flags>, except that it
-does not accept the C<XPI_OPERAND_LIST> value. Parsing always happens on just
-a term expression, though it may be placed into list context (which therefore
-still permits things like parenthesized lists, or array variables).
-
=head2 The Selection Stage
The C<cls> field gives a "classification" of the operator, suggesting what
@@ -214,6 +218,18 @@
If neither is present then the keyword is always permitted - which is likely
not what you wanted to do.
+=head2 The C<parse> Stage
+
+If the optional C<parse> hook function is present, it is called immediately
+after the parser has recognised the presence of the named operator itself but
+before it attempts to consume the right-hand side term. This hook function can
+attempt further parsing, in order to implement more complex syntax such as
+hyper-operators.
+
+When invoked, it is passed a pointer to an C<ANY>-typed storage variable. It
+is free to use whichever field of this variable it desires to store a result,
+which will then later be made available to the C<new_op> function.
+
=head2 The Op Generation Stage
If the infix operator is going to be used, then one of the C<new_op> or the
@@ -221,8 +237,14 @@
If C<new_op> is defined then it will be used, and is expected to return an
optree fragment that consumes the LHS and RHS arguments to implement the
-semantics of the operator. If this is not present, then the C<ppaddr> will be
-used instead to construct a new BINOP of the C<OP_CUSTOM> type.
+semantics of the operator. If the optional C<parse> stage had been present
+earlier, the C<ANY> pointer passed here will point to the same storage that
+C<parse> had previously had access to, so it can retrieve the results.
+
+If C<new_op> is not present, then the C<ppaddr> will be used instead to
+construct a new BINOP of the C<OP_CUSTOM> type. If an earlier C<parse> stage
+had stored additional results into the C<ANY> variable these will be lost
+here.
=head2 The Wrapper Function
@@ -322,6 +344,11 @@
The first registration will create the wrapper function; the subsequent one
will skip it because it would otherwise be identical.
+Note that when generating an optree for a wrapper function call, the C<new_op>
+hook function will be invoked with a C<NULL> pointer for the C<ANY>-typed
+parse data storage, as there won't be an opporunity for the C<parse> hook to
+run in this case.
+
=cut
=head1 DEPARSE
@@ -423,6 +450,12 @@
anon-array argument forms (C<WRAPPERFUNC( \@lhs, \@rhs )> or
C<WRAPPERFUNC( [LHS], [RHS] )>).
+=item *
+
+Further thoughts about how infix operators with C<parse> hooks will work with
+automatic deparse, and also how to integrate them with L<XS::Parse::Keyword>'s
+grammar piece.
+
=back
=cut
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword/Builder.pm
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder.pm
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword/Builder.pm 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder.pm 2022-10-31
23:09:16.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021 -- [email protected]
-package XS::Parse::Keyword::Builder 0.25;
+package XS::Parse::Keyword::Builder 0.27;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword/Builder_data.pm.PL
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder_data.pm.PL
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword/Builder_data.pm.PL
2022-07-26 00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword/Builder_data.pm.PL
2022-10-31 23:09:16.000000000 +0100
@@ -28,7 +28,7 @@
<$in_h> } );
__DATA__
-package XS::Parse::Keyword::Builder_data 0.25;
+package XS::Parse::Keyword::Builder_data 0.27;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword.pm
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.pm
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword.pm 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.pm 2022-10-31
23:09:16.000000000 +0100
@@ -3,7 +3,7 @@
#
# (C) Paul Evans, 2021-2022 -- [email protected]
-package XS::Parse::Keyword 0.25;
+package XS::Parse::Keyword 0.27;
use v5.14;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword.xs
new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.xs
--- old/XS-Parse-Keyword-0.25/lib/XS/Parse/Keyword.xs 2022-07-26
00:36:23.000000000 +0200
+++ new/XS-Parse-Keyword-0.27/lib/XS/Parse/Keyword.xs 2022-10-31
23:09:16.000000000 +0100
@@ -30,18 +30,64 @@
static void XSParseInfix_register_v0(pTHX_ const char *opname, const struct
XSParseInfixHooks_v0 *hooks_v0, void *hookdata)
{
+ warn("XSParseInfix ABI version 0 is deprecated and will soon be removed");
+
struct XSParseInfixHooks *hooks;
Newx(hooks, 1, struct XSParseInfixHooks);
- hooks->flags = hooks_v0->flags;
+ hooks->flags = hooks_v0->flags | (1<<15); /* NO_PARSEDATA */
hooks->cls = hooks_v0->cls;
hooks->wrapper_func_name = NULL;
hooks->permit_hintkey = hooks_v0->permit_hintkey;
hooks->permit = hooks_v0->permit;
- hooks->new_op = hooks_v0->new_op;
+ hooks->new_op = (OP *(*)(pTHX_ U32, OP *, OP *, SV **, void
*))hooks_v0->new_op;
hooks->ppaddr = hooks_v0->ppaddr;
+ hooks->parse = NULL;
+
+ XSParseInfix_register(aTHX_ opname, hooks, hookdata);
+}
+
+/* v1 hooks.newop did not pass parsedata */
+struct XSParseInfixHooks_v1 {
+ U16 flags;
+ U8 lhs_flags, rhs_flags;
+ enum XSParseInfixClassification cls;
+
+ const char *wrapper_func_name;
+
+ const char *permit_hintkey;
+ bool (*permit) (pTHX_ void *hookdata);
+
+ OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
+ OP *(*ppaddr)(pTHX);
+
+ OP *(*parse_rhs)(pTHX_ void *hookdata);
+};
+
+static void XSParseInfix_register_v1(pTHX_ const char *opname, const struct
XSParseInfixHooks_v1 *hooks_v1, void *hookdata)
+{
+ if(hooks_v1->rhs_flags & XPI_OPERAND_CUSTOM)
+ croak("XPI_OPERAND_CUSTOM is no longer supported");
+ if(hooks_v1->parse_rhs)
+ croak("XSParseInfixHooks.parse_rhs is no longer supported");
+
+ struct XSParseInfixHooks *hooks;
+ Newx(hooks, 1, struct XSParseInfixHooks);
+
+ hooks->flags = hooks_v1->flags | (1<<15) /* NO_PARSEDATA */;
+ hooks->lhs_flags = hooks_v1->lhs_flags;
+ hooks->rhs_flags = hooks_v1->rhs_flags;
+ hooks->cls = hooks_v1->cls;
+
+ hooks->wrapper_func_name = hooks_v1->wrapper_func_name;
+
+ hooks->permit_hintkey = hooks_v1->permit_hintkey;
+ hooks->permit = hooks_v1->permit;
+ hooks->new_op = (OP *(*)(pTHX_ U32, OP *, OP *, SV **, void
*))hooks_v1->new_op;
+ hooks->ppaddr = hooks_v1->ppaddr;
+ hooks->parse = NULL;
XSParseInfix_register(aTHX_ opname, hooks, hookdata);
}
@@ -65,8 +111,10 @@
sv_setiv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MIN", 1), 0);
sv_setiv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/ABIVERSION_MAX", 1),
XSPARSEINFIX_ABI_VERSION);
+ sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/parse()@2", 1),
PTR2UV(&XSParseInfix_parse));
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/new_op()@0", 1),
PTR2UV(&XSParseInfix_new_op));
sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@0", 1),
PTR2UV(&XSParseInfix_register_v0));
- sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@1", 1),
PTR2UV(&XSParseInfix_register));
+ sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@1", 1),
PTR2UV(&XSParseInfix_register_v1));
+ sv_setuv(*hv_fetchs(PL_modglobal, "XS::Parse::Infix/register()@2", 1),
PTR2UV(&XSParseInfix_register));
XSParseInfix_boot(aTHX);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/src/infix.c
new/XS-Parse-Keyword-0.27/src/infix.c
--- old/XS-Parse-Keyword-0.25/src/infix.c 2022-07-26 00:36:23.000000000
+0200
+++ new/XS-Parse-Keyword-0.27/src/infix.c 2022-10-31 23:09:16.000000000
+0100
@@ -13,6 +13,7 @@
#include "infix.h"
#include "perl-backcompat.c.inc"
+#include "optree-additions.c.inc"
#include "force_list_keeping_pushmark.c.inc"
#include "make_argcheck_ops.c.inc"
@@ -75,9 +76,7 @@
{
U8 lhs_gimme;
switch(hd->hooks->lhs_flags & 0x07) {
- case 0: /* back-compat */
- case XPI_OPERAND_ARITH:
- case XPI_OPERAND_TERM:
+ case 0:
lhs_gimme = G_SCALAR;
break;
@@ -93,9 +92,7 @@
U8 rhs_gimme;
switch(hd->hooks->rhs_flags & 0x07) {
- case 0: /* back-compat */
- case XPI_OPERAND_ARITH:
- case XPI_OPERAND_TERM:
+ case 0:
rhs_gimme = G_SCALAR;
break;
@@ -150,10 +147,16 @@
static struct Registration *registrations;
-static OP *new_op(pTHX_ const struct HooksAndData hd, U32 flags, OP *lhs, OP
*rhs)
+static OP *new_op(pTHX_ const struct HooksAndData hd, U32 flags, OP *lhs, OP
*rhs, SV **parsedata)
{
- if(hd.hooks->new_op)
- return (*hd.hooks->new_op)(aTHX_ flags, lhs, rhs, hd.data);
+ if(hd.hooks->new_op) {
+ if(hd.hooks->flags & (1<<15)) {
+ OP *(*new_op_v1)(pTHX_ U32, OP *, OP *, void *) = (OP *(*)(pTHX_ U32, OP
*, OP *, void *))hd.hooks->new_op;
+ return (*new_op_v1)(aTHX_ flags, lhs, rhs, hd.data); /* no parsedata */
+ }
+
+ return (*hd.hooks->new_op)(aTHX_ flags, lhs, rhs, parsedata, hd.data);
+ }
OP *ret = newBINOP_CUSTOM(hd.hooks->ppaddr, flags, lhs, rhs);
@@ -231,51 +234,40 @@
#ifdef HAVE_PL_INFIX_PLUGIN
-OP *parse(pTHX_ OP *lhs, struct Perl_custom_infix *def)
+void parse(pTHX_ SV **parsedata, struct Perl_custom_infix *def)
+{
+ struct Registration *reg = (struct Registration *)def;
+
+ (*reg->hd.hooks->parse)(aTHX_ 0, parsedata, reg->hd.data);
+}
+
+OP *build_op(pTHX_ SV **parsedata, OP *lhs, OP *rhs, struct Perl_custom_infix
*def)
{
struct Registration *reg = (struct Registration *)def;
switch(reg->hd.hooks->lhs_flags & 0x07) {
- case XPI_OPERAND_TERM:
+ case 0:
break;
case XPI_OPERAND_TERM_LIST:
+ case XPI_OPERAND_LIST:
lhs = force_list_keeping_pushmark(lhs);
break;
}
/* TODO: maybe operator has a 'parse' hook? */
- lex_read_space(0);
- OP *rhs = NULL;
-
- switch(reg->hd.hooks->rhs_flags & 0x87) {
- case XPI_OPERAND_ARITH:
- rhs = parse_arithexpr(0);
- break;
-
- case 0: /* back-compat */
- case XPI_OPERAND_TERM:
- rhs = parse_termexpr(0);
+ switch(reg->hd.hooks->rhs_flags & 0x07) {
+ case 0:
break;
case XPI_OPERAND_TERM_LIST:
- rhs = force_list_keeping_pushmark(parse_termexpr(0));
- break;
-
case XPI_OPERAND_LIST:
- rhs = force_list_keeping_pushmark(parse_listexpr(0));
- break;
-
- case XPI_OPERAND_CUSTOM:
- rhs = (*reg->hd.hooks->parse_rhs)(aTHX_ reg->hd.data);
+ rhs = force_list_keeping_pushmark(rhs);
break;
-
- default:
- croak("hooks->rhs_flags did not provide a valid RHS type");
}
- return new_op(aTHX_ reg->hd, 0, lhs, rhs);
+ return new_op(aTHX_ reg->hd, 0, lhs, rhs, parsedata);
}
static STRLEN (*next_infix_plugin)(pTHX_ char *, STRLEN, struct
Perl_custom_infix **);
@@ -380,7 +372,7 @@
return new_op(aTHX_ (struct HooksAndData) {
.hooks = info->hooks,
.data = info->hookdata,
- }, flags, lhs, rhs);
+ }, flags, lhs, rhs, NULL);
return newBINOP(info->opcode, flags, lhs, rhs);
}
@@ -470,7 +462,7 @@
if(!extract_wrapper2_args(aTHX_ op, &left, &right))
return op;
- return new_op(aTHX_ *hd, 0, left, right);
+ return new_op(aTHX_ *hd, 0, left, right, NULL);
}
static OP *ckcall_wrapper_func_listlist(pTHX_ OP *op, GV *namegv, SV *ckobj)
@@ -483,21 +475,16 @@
return new_op(aTHX_ *hd, 0,
unwrap_list(left, hd->hooks->lhs_flags & XPI_OPERAND_ONLY_LOOK),
- unwrap_list(right, hd->hooks->rhs_flags & XPI_OPERAND_ONLY_LOOK));
-}
-
-#define newSLUGOP(idx) S_newSLUGOP(aTHX_ idx)
-static OP *S_newSLUGOP(pTHX_ int idx)
-{
- OP *op = newGVOP(OP_AELEMFAST, 0, PL_defgv);
- op->op_private = idx;
- return op;
+ unwrap_list(right, hd->hooks->rhs_flags & XPI_OPERAND_ONLY_LOOK),
+ NULL);
}
static void make_wrapper_func(pTHX_ const struct HooksAndData *hd)
{
SV *funcname = newSVpvn(hd->hooks->wrapper_func_name,
strlen(hd->hooks->wrapper_func_name));
- if(gv_fetchsv(funcname, 0, 0)) {
+
+ GV *gv;
+ if((gv = gv_fetchsv(funcname, 0, 0)) && GvCV(gv)) {
/* The wrapper function already exists. We presume this is due to a
duplicate
* registration of identical hooks under a different name and just skip
*/
@@ -523,7 +510,7 @@
/* Body of the function is just $_[0] OP $_[1] */
body = op_append_list(OP_LINESEQ, body,
- new_op(aTHX_ *hd, 0, newSLUGOP(0), newSLUGOP(1)));
+ new_op(aTHX_ *hd, 0, newSLUGOP(0), newSLUGOP(1), NULL));
ckcall = &ckcall_wrapper_func_scalarscalar;
break;
@@ -539,7 +526,8 @@
body = op_append_list(OP_LINESEQ, body,
new_op(aTHX_ *hd, 0,
newOP(OP_SHIFT, 0),
- force_list_keeping_pushmark(newUNOP(OP_RV2AV, OPf_WANT_LIST,
newGVOP(OP_GV, 0, PL_defgv)))));
+ force_list_keeping_pushmark(newUNOP(OP_RV2AV, OPf_WANT_LIST,
newGVOP(OP_GV, 0, PL_defgv))),
+ NULL));
/* no ckcall */
break;
@@ -555,7 +543,8 @@
body = op_append_list(OP_LINESEQ, body,
new_op(aTHX_ *hd, 0,
force_list_keeping_pushmark(newUNOP(OP_RV2AV, 0, newSLUGOP(0))),
- force_list_keeping_pushmark(newUNOP(OP_RV2AV, 0, newSLUGOP(1)))));
+ force_list_keeping_pushmark(newUNOP(OP_RV2AV, 0, newSLUGOP(1))),
+ NULL));
ckcall = &ckcall_wrapper_func_listlist;
break;
@@ -665,6 +654,8 @@
void XSParseInfix_register(pTHX_ const char *opname, const struct
XSParseInfixHooks *hooks, void *hookdata)
{
switch(hooks->flags) {
+ case (1<<15):
+ /* undocumented internal flag to indicate v1-compatible ->new_op hook
function */
case 0:
break;
default:
@@ -673,10 +664,8 @@
switch(hooks->lhs_flags & ~(XPI_OPERAND_ONLY_LOOK)) {
case 0:
- //warn("No .lhs_flags specified for XSParseInfixHooks; defaulting to
XPI_OPERAND_TERM");
- /* FALLTHROUGH */
- case XPI_OPERAND_TERM:
case XPI_OPERAND_TERM_LIST:
+ case XPI_OPERAND_LIST:
break;
default:
croak("Unrecognised XSParseInfixHooks.lhs_flags value 0x%X",
hooks->lhs_flags);
@@ -684,23 +673,57 @@
switch(hooks->rhs_flags & ~(XPI_OPERAND_ONLY_LOOK)) {
case 0:
- //warn("No .rhs_flags specified for XSParseInfixHooks; defaulting to
XPI_OPERAND_TERM");
- /* FALLTHROUGH */
- case XPI_OPERAND_ARITH:
- case XPI_OPERAND_TERM:
case XPI_OPERAND_TERM_LIST:
case XPI_OPERAND_LIST:
- case XPI_OPERAND_CUSTOM:
break;
default:
croak("Unrecognised XSParseInfixHooks.rhs_flags value 0x%X",
hooks->rhs_flags);
+
+ case XPI_OPERAND_CUSTOM:
+ croak("TODO: Currently XPI_OPERAND_CUSTOM is not supported");
+ }
+
+#ifdef HAVE_PL_INFIX_PLUGIN
+ enum Perl_custom_infix_precedence prec = 0;
+
+ switch(hooks->cls) {
+ case 0:
+ warn("Unspecified operator classification for %s; treating it as
RELATION for precedence", opname);
+ case XPI_CLS_RELATION:
+ case XPI_CLS_EQUALITY:
+ case XPI_CLS_MATCH_MISC:
+ prec = INFIX_PREC_REL;
+ break;
+
+ case XPI_CLS_ADD_MISC:
+ prec = INFIX_PREC_ADD;
+ break;
+
+ case XPI_CLS_MUL_MISC:
+ prec = INFIX_PREC_MUL;
+ break;
+
+ case XPI_CLS_POW_MISC:
+ prec = INFIX_PREC_POW;
+ break;
+
+ /* TODO: Add classifications for the HIGH and LOW also? */
+
+ default:
+ croak("TODO: need to write code for hooks->cls == %d\n", hooks->cls);
}
+#endif
struct Registration *reg;
Newx(reg, 1, struct Registration);
#ifdef HAVE_PL_INFIX_PLUGIN
- reg->def.parse = &parse;
+ reg->def.prec = prec;
+ if(hooks->parse)
+ reg->def.parse = &parse;
+ else
+ reg->def.parse = NULL;
+ reg->def.build_op = &build_op;
#endif
reg->info.opname = savepv(opname);
@@ -815,11 +838,6 @@
));
#ifdef HAVE_PL_INFIX_PLUGIN
- OP_CHECK_MUTEX_LOCK;
- if(!next_infix_plugin) {
- next_infix_plugin = PL_infix_plugin;
- PL_infix_plugin = &my_infix_plugin;
- }
- OP_CHECK_MUTEX_UNLOCK;
+ wrap_infix_plugin(&my_infix_plugin, &next_infix_plugin);
#endif
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/t/70infix.t
new/XS-Parse-Keyword-0.27/t/70infix.t
--- old/XS-Parse-Keyword-0.25/t/70infix.t 2022-07-26 00:36:23.000000000
+0200
+++ new/XS-Parse-Keyword-0.27/t/70infix.t 2022-10-31 23:09:16.000000000
+0100
@@ -87,9 +87,30 @@
"infix_add_0xXXX[aelemfast, aelemfast]",
'optree of call to infix operator';
+ # Check precedence of operator parsing by observing the following precedence
+ # ordering:
+ # <--High Low-->
+ # ** * + &&
+
is_optree sub { $_[0] * $_[1] add $_[2] * $_[3] },
"infix_add_0xXXX[multiply[aelemfast, aelemfast], multiply[aelemfast,
aelemfast]]",
- 'optree of call to infix operator at default precedence';
+ 'optree binds add lower than *';
+ is_optree sub { $_[0] + $_[1] add $_[2] + $_[3] },
+ "add[infix_add_0xXXX[add[aelemfast, aelemfast], aelemfast], aelemfast]",
+ 'optree binds add equal to +';
+ is_optree sub { $_[0] && $_[1] add $_[2] && $_[3] },
+ "and[and[aelemfast, infix_add_0xXXX[aelemfast, aelemfast]], aelemfast]",
+ 'optree binds add higher than &&';
+
+ is_optree sub { $_[0] ** $_[1] mul $_[2] ** $_[3] },
+ "infix_mul_0xXXX[pow[aelemfast, aelemfast], pow[aelemfast, aelemfast]]",
+ 'optree binds mul lower than **';
+ is_optree sub { $_[0] * $_[1] mul $_[2] * $_[3] },
+ "multiply[infix_mul_0xXXX[multiply[aelemfast, aelemfast], aelemfast],
aelemfast]",
+ 'optree binds mul equal to *';
+ is_optree sub { $_[0] + $_[1] mul $_[2] + $_[3] },
+ "add[add[aelemfast, infix_mul_0xXXX[aelemfast, aelemfast]], aelemfast]",
+ 'optree binds mul higher than +';
is_optree sub { $_[0] * ($_[1] add $_[2]) * $_[3] },
"multiply[multiply[aelemfast, infix_add_0xXXX[aelemfast, aelemfast]],
aelemfast]",
@@ -116,11 +137,11 @@
{
is_deparsed sub { $_[0] add $_[1] },
'$_[0] add $_[1];',
- 'deparsed call to infix operator';
+ 'deparsed call to infix add operator';
is_deparsed sub { $_[0] * $_[1] add $_[2] * $_[3] },
'($_[0] * $_[1]) add ($_[2] * $_[3]);',
- 'deparsed call to infix operator at default precedence';
+ 'deparsed call to infix add operator at default precedence';
is_deparsed sub { $_[0] ??? $_[1] },
'$_[0] ??? $_[1];',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/XS-Parse-Keyword-0.25/t/infix.xs
new/XS-Parse-Keyword-0.27/t/infix.xs
--- old/XS-Parse-Keyword-0.25/t/infix.xs 2022-07-26 00:36:23.000000000
+0200
+++ new/XS-Parse-Keyword-0.27/t/infix.xs 2022-10-31 23:09:16.000000000
+0100
@@ -26,16 +26,26 @@
}
static const struct XSParseInfixHooks hooks_add = {
- .lhs_flags = XPI_OPERAND_TERM,
- .rhs_flags = XPI_OPERAND_TERM,
+ .cls = XPI_CLS_ADD_MISC,
.permit_hintkey = hintkey,
- .cls = 0,
.wrapper_func_name = "t::infix::addfunc",
.ppaddr = &pp_add,
};
+OP *pp_mul(pTHX)
+{
+ croak("TODO"); /* We never actually call code with this so it doesn't matter
*/
+}
+
+static const struct XSParseInfixHooks hooks_mul = {
+ .cls = XPI_CLS_MUL_MISC,
+ .permit_hintkey = hintkey,
+
+ .ppaddr = &pp_mul,
+};
+
OP *pp_xor(pTHX)
{
dSP;
@@ -46,10 +56,8 @@
}
static const struct XSParseInfixHooks hooks_xor = {
- .lhs_flags = XPI_OPERAND_TERM,
- .rhs_flags = XPI_OPERAND_TERM,
+ .cls = XPI_CLS_ADD_MISC,
.permit_hintkey = hintkey,
- .cls = 0,
.ppaddr = &pp_xor,
};
@@ -86,10 +94,9 @@
}
static const struct XSParseInfixHooks hooks_intersperse = {
- .lhs_flags = XPI_OPERAND_TERM,
+ .cls = XPI_CLS_ADD_MISC,
.rhs_flags = XPI_OPERAND_LIST,
.permit_hintkey = hintkey,
- .cls = 0,
.wrapper_func_name = "t::infix::interspersefunc",
@@ -124,10 +131,10 @@
}
static const struct XSParseInfixHooks hooks_addpairs = {
- .lhs_flags = XPI_OPERAND_TERM_LIST,
- .rhs_flags = XPI_OPERAND_TERM_LIST|XPI_OPERAND_ONLY_LOOK, /* only on RHS so
we can test the logic */
+ .cls = XPI_CLS_ADD_MISC,
+ .lhs_flags = XPI_OPERAND_LIST,
+ .rhs_flags = XPI_OPERAND_LIST|XPI_OPERAND_ONLY_LOOK, /* only on RHS so we
can test the logic */
.permit_hintkey = hintkey,
- .cls = 0,
.wrapper_func_name = "t::infix::addpairsfunc",
@@ -140,6 +147,7 @@
boot_xs_parse_infix(0);
register_xs_parse_infix("add", &hooks_add, NULL);
+ register_xs_parse_infix("mul", &hooks_mul, NULL);
register_xs_parse_infix("???", &hooks_xor, NULL);