1XS::Parse::Infix(3)   User Contributed Perl Documentation  XS::Parse::Infix(3)
2
3
4

NAME

6       "XS::Parse::Infix" - XS functions to assist in parsing infix operators
7

DESCRIPTION

9       This module provides some XS functions to assist in writing syntax
10       modules that provide new infix operators as perl syntax, primarily for
11       authors of syntax plugins. It is unlikely to be of much use to anyone
12       else; and highly unlikely to be of any use when writing perl code using
13       these. Unless you are writing a syntax plugin using XS, this module is
14       not for you.
15
16       This module is also currently experimental, and the design is still
17       evolving and subject to change. Later versions may break ABI
18       compatibility, requiring changes or at least a rebuild of any module
19       that depends on it.
20
21       In addition, the places this functionality can be used are relatively
22       small.  No current release of perl actually supports custom infix
23       operators, though I have a branch where I am currently experimenting
24       with such support:
25
26       <https://github.com/leonerd/perl5/tree/infix-plugin>
27
28       In addition, the various "XPK_INFIX_*" token types of
29       XS::Parse::Keyword support querying on this module, so some syntax
30       provided by other modules may be able to make use of these new infix
31       operators.
32

CONSTANTS

34   HAVE_PL_INFIX_PLUGIN
35          if( XS::Parse::Infix::HAVE_PL_INFIX_PLUGIN ) { ... }
36
37       This constant is true if built on a perl that supports the
38       "PL_infix_plugin" extension mechanism, meaning that custom infix
39       operators registered with this module will actually be recognised by
40       the perl parser.
41
42       No actual production or development releases of perl yet support this
43       feature, but see above for details of a branch which does.
44

XS FUNCTIONS

46   boot_xs_parse_infix
47         void boot_xs_parse_infix(double ver);
48
49       Call this function from your "BOOT" section in order to initialise the
50       module and parsing hooks.
51
52       ver should either be 0 or a decimal number for the module version
53       requirement; e.g.
54
55          boot_xs_parse_infix(0.14);
56
57   xs_parse_infix_new_op
58          OP *xs_parse_infix_new_op(const struct XSParseInfixInfo *info, U32 flags,
59             OP *lhs, OP *rhs);
60
61       This function constructs a new optree fragment to represent invoking
62       the infix operator with the given operands. It should be used much the
63       same as core perl's "newBINOP" function.
64
65       The "info" structure pointer would be obtained from the "infix" field
66       of the result of invoking the various "XPK_INFIX_*" token types from
67       "XS::Parse::Keyword".
68
69   register_xs_parse_infix
70          void register_xs_parse_infix(const char *opname,
71             const struct XSParseInfixHooks *hooks, void *hookdata);
72
73       This function installs a set of parsing hooks to be associated with the
74       given operator name. This new operator will then be available via
75       XS::Parse::Keyword by the various "XPK_INFIX_*" token types, or to core
76       perl's "PL_infix_plugin" if availble.
77
78       These tokens will all yield an info structure, with the following
79       fields:
80
81          struct XSParseInfixInfo {
82             const char *opname;
83             OPCODE opcode;  /* for built-in operators, or OP_CUSTOM for
84                                custom-registered ones */
85
86             struct XSParseInfixHooks *hooks;
87             void                     *hookdata;
88          };
89
90       If the operator name contains any non-ASCII characters they are
91       presumed to be in UTF-8 encoding. This will matter for deparse
92       purposes.
93

PARSE HOOKS

95       The "XSParseInfixHooks" structure provides the following fields which
96       are used at various stages of parsing.
97
98          struct XSParseInfixHooks {
99             U16 flags; /* currently ignored */
100             U8 lhs_flags;
101             U8 rhs_flags;
102             enum XSParseInfixClassification cls;
103
104             const char *wrapper_func_name;
105
106             const char *permit_hintkey;
107             bool (*permit)(pTHX_ void *hookdata);
108
109             OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
110             OP *(*ppaddr)(pTHX);
111          };
112
113   Flags
114       The "flags" field is currently ignored. It is defined simply to reserve
115       the space in case used in a later version. It should be set to zero.
116
117       The "rhs_flags" field gives details on how to parse and handle the
118       right-hand side of the operator syntax. It should be set to one of the
119       following constants:
120
121       XPI_OPERAND_ARITH
122           The operand is an arithmetic expression.
123
124       XPI_OPERAND_TERM
125           The operand is a term expression.
126
127       XPI_OPERAND_TERM_LIST
128           The operand is a term expression. It will be foced into list
129           context, preserving the "OP_PUSHMARK" at the beginning. This means
130           that the ppfunc for this infix operator will have to "POPMARK" to
131           find that.
132
133       XPI_OPERAND_LIST
134           The operand is a list expression. It will be forced into list
135           context, the same as above.
136
137       In addition the following extra bitflags are defined:
138
139       XPI_OPERAND_ONLY_LOOK
140           If set, the operator function promises that it will not mutate any
141           of its passed values, nor allow leaking of direct alias pointers to
142           them via return value or other locations.
143
144           This flag is optional; omitting it when applicable will not change
145           any observed behaviour. Setting it may enable certain optimisations
146           to be performed.
147
148           Currently, this flag simply enables an optimisation in the call-
149           checker for infix operator wrapper functions that take list-shaped
150           operands. This optimisation discards an "OP_ANONLIST" operation
151           which would create a temporary anonymous array reference for its
152           operand values, allowing a slight saving of memory use and CPU
153           time. This optimisation is only safe to perform if the operator
154           does not mutate or retain aliases of any of the arguments, as
155           otherwise the caller might see unexpected modifications or value
156           references to the values passed.
157
158       The "lhs_flags" field gives details on how to handle the left-hand side
159       of the operator syntax. It takes similar values to "rhs_flags", except
160       that it does not accept the "XPI_OPERAND_LIST" value. Parsing always
161       happens on just a term expression, though it may be placed into list
162       context (which therefore still permits things like parenthesized lists,
163       or array variables).
164
165   The Selection Stage
166       The "cls" field gives a "classification" of the operator, suggesting
167       what sort of operation it provides. This is used as a filter by the
168       various "XS::Parse::Keyword" selection macros.
169
170       The classification should be one of the "XPI_CLS_*" constants found and
171       described further in the main XSParseInfix.h file.
172
173   The "permit" Stage
174       As a shortcut for the common case, the "permit_hintkey" may point to a
175       string to look up from the hints hash. If the given key name is not
176       found in the hints hash then the keyword is not permitted. If the key
177       is present then the "permit" function is invoked as normal.
178
179       If not rejected by a hint key that was not found in the hints hash, the
180       function part of the stage is called next and should inspect whether
181       the keyword is permitted at this time perhaps by inspecting other
182       lexical clues, and return true only if the keyword is permitted.
183
184       Both the string and the function are optional. Either or both may be
185       present.  If neither is present then the keyword is always permitted -
186       which is likely not what you wanted to do.
187
188   The Op Generation Stage
189       If the infix operator is going to be used, then one of the "new_op" or
190       the "ppaddr" fields explain how to create a new optree fragment.
191
192       If "new_op" is defined then it will be used, and is expected to return
193       an optree fragment that consumes the LHS and RHS arguments to implement
194       the semantics of the operator. If this is not present, then the
195       "ppaddr" will be used instead to construct a new BINOP of the
196       "OP_CUSTOM" type.
197
198   The Wrapper Function
199       Additionally, if the "wrapper_func_name" field is set to a string, this
200       gives the (fully-qualified) name for a function to be generated as part
201       of registering the operator. This newly-generated function will act as
202       a wrapper for the operator.
203
204       For operators whose RHS is a scalar, the wrapper function is assumed to
205       take two simple scalar arguments. The result of invoking the function
206       on those arguments will be determined by using the operator code.
207
208          $result = $lhs OP $rhs;
209
210          $result = WRAPPERFUNC( $lhs, $rhs );
211
212       For operators whose RHS is a list, the wrapper function takes at least
213       one argument, possibly more. The first argument is the scalar on the
214       LHS, and the remaining arguments, however many there are, form the RHS:
215
216          $result = $lhs OP @rhs;
217
218          $result = WRAPPERFUNC( $lhs, @rhs );
219
220       For operators whose LHS and RHS is a list, the wrapper function takes
221       two arguments which must be array references containing the lists.
222
223          $result = @lhs OP @rhs;
224
225          $result = WRAPPERFUNC( \@lhs, \@rhs );
226
227       This creates a convenience for accessing the operator from perls that
228       do not support "PL_infix_plugin".
229
230       In the case of scalar infix operators, the wrapper function also
231       includes a call-checker which attempts to inline the operator directly
232       into the callsite.  Thus, in simple cases where the function is called
233       directly on exactly two scalar arguments (such as in the following), no
234       "ENTERSUB" overhead will be incurred and the generated optree will be
235       identical to that which would have been generated by using infix
236       operator syntax directly:
237
238          WRAPPERFUNC( $lhs, $rhs );
239          WRAPPERFUNC( $lhs, CONSTANT );
240          WRAPPERFUNC( $args[0], $args[1] );
241          WRAPPERFUNC( $lhs, scalar otherfunc() );
242
243       The checker is very pessimistic and will only rewrite callsites where
244       it determines this can be done safely. It will not rewrite any of the
245       following forms:
246
247          WRAPPERFUNC( $onearg );            # not enough args
248          WRAPPERFUNC( $x, $y, $z );         # too many args
249          WRAPPERFUNC( @args[0,1] );         # not a scalar
250          WRAPPERFUNC( $lhs, otherfunc() );  # not a scalar
251
252       The wrapper function for infix operators which take lists on both sides
253       also has a call-checker which will attempt to inline the operator in
254       similar circumstances. In addition to the optimisations described above
255       for scalar operators, this checker will also inline an array-reference
256       operator and omit the resulting dereference behaviour. Thus, the two
257       following lines emit the same optree, without an "OP_SREFGEN" or
258       "OP_RV2AV":
259
260          @lhs OP @rhs;
261          WRAPPERFUNC( \@lhs, \@rhs );
262
263       Note that technically, this optimisation isn't strictly transparent in
264       the odd cornercase that one of the referenced arrays is also the
265       backing store for a blessed object reference, and that object class has
266       a "@{}" overload.
267
268          my @arr;
269          package SomeClass {
270             use overload '@{}' => sub { return ["values", "go", "here"]; };
271          }
272          bless \@arr, "SomeClass";
273
274          # this will not actually invoke the overload operator
275          WRAPPERFUNC( \@arr, [4, 5, 6] );
276
277       As this cornercase relates to taking duplicate references to the same
278       blessed object's backing store variable, it should not matter to any
279       real code; regular objects that are passed by reference into the
280       wrapper function will run their overload methods as normal.
281
282       The callchecker for list operands can optionally also discard an op of
283       the "OP_ANONLIST" type, which is used by anonymous array-ref
284       construction:
285
286          ($u, $v, $w) OP ($x, $y, $z);
287          WRAPPERFUNC( [$u, $v, $w], [$x, $y, $z] );
288
289       This optimisation is only performed if the operator declared it safe to
290       do so, via the "XPI_OPERAND_ONLY_LOOK" flag.
291
292       If a function of the given name already exists at registration time it
293       will be left undisturbed and no new wrapper will be created. This
294       permits the same infix operator to have multiple spellings of its name;
295       for example to allow both a real Unicode and a fallback ASCII
296       transliteration of the same operator.  The first registration will
297       create the wrapper function; the subsequent one will skip it because it
298       would otherwise be identical.
299

DEPARSE

301       This module operates with B::Deparse in order to automatically provide
302       deparse support for infix operators. Every infix operator that is
303       implemented as a custom op (and thus has the "ppaddr" hook field set)
304       will have deparse logic added. This will allow it to deparse to either
305       the named wrapper function, or to the infix operator syntax if on a
306       "PL_infix_plugin"-enabled perl and the appropriate lexical hint is
307       enabled at the callsite.
308
309       In order for this to work, it is important that your custom operator is
310       not registered as a custom op using the "Perl_register_custom_op()"
311       function.  This registration will be performed by "XS::Parse::Infix"
312       itself at the time the infix operator is registered.
313

TODO

315       •   Have the entersub checker for list/list operators unwrap arrayref
316           or anon-array argument forms ("WRAPPERFUNC( \@lhs, \@rhs )" or
317           "WRAPPERFUNC( [LHS], [RHS] )").
318

AUTHOR

320       Paul Evans <leonerd@leonerd.org.uk>
321
322
323
324perl v5.36.0                      2022-07-26               XS::Parse::Infix(3)
Impressum