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