File Coverage

blib/lib/XS/Parse/Sublike.pm
Criterion Covered Total %
statement 5 5 100.0
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 7 7 100.0


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2020-2024 -- leonerd@leonerd.org.uk
5              
6             package XS::Parse::Sublike 0.41;
7              
8 28     28   6603475 use v5.14;
  28         125  
9 28     28   225 use warnings;
  28         133  
  28         5673  
10              
11             require XSLoader;
12             XSLoader::load( __PACKAGE__, our $VERSION );
13              
14             =encoding UTF-8
15              
16             =head1 NAME
17              
18             C - XS functions to assist in parsing C-like syntax
19              
20             =head1 DESCRIPTION
21              
22             This module provides some XS functions to assist in writing parsers for
23             C-like syntax, primarily for authors of keyword plugins using the
24             C hook mechanism. It is unlikely to be of much use to
25             anyone else; and highly unlikely to be any use when writing perl code using
26             these. Unless you are writing a keyword plugin using XS, this module is not
27             for you.
28              
29             This module is also currently experimental, and the design is still evolving
30             and subject to change. Later versions may break ABI compatibility, requiring
31             changes or at least a rebuild of any module that depends on it.
32              
33             =head1 XS FUNCTIONS
34              
35             =for highlighter language=c
36              
37             =head2 boot_xs_parse_sublike
38              
39             void boot_xs_parse_sublike(double ver)
40              
41             Call this function from your C section in order to initialise the module
42             and parsing hooks.
43              
44             I should either be 0 or a decimal number for the module version
45             requirement; e.g.
46              
47             boot_xs_parse_sublike(0.04);
48              
49             =head2 xs_parse_sublike
50              
51             int xs_parse_sublike(const struct XSParseSublikeHooks *hooks, void *hookdata, OP **op_ptr)
52              
53             This function performs the actual parsing of a C-like keyword. It expects
54             the lexer to be at a position just after the introduction keyword has been
55             consumed, and will proceed to parse an optional name, list of attributes,
56             signature (if enabled by C), and code body. The
57             return value and C can be used directly from the keyword plugin
58             function. It is intended this function be invoked from it, and the result
59             returned directly.
60              
61             For a more automated handling of keywords, see L.
62              
63             I should be a structure that can provide optional function pointers
64             used to customise the parsing process at various stages. I is an
65             opaque pointer which is passed through to each of the hook stage functions.
66              
67             =head2 register_xs_parse_sublike
68              
69             void register_xs_parse_sublike(const char *keyword,
70             const struct XSParseSublikeHooks *hooks, void *hookdata)
71              
72             This function installs a set of parsing hooks to be associated with the given
73             keyword. Such a keyword will then be handled automatically by a keyword parser
74             installed by C itself.
75              
76             When the keyword is encountered, the hook's C function is first tested
77             to see if the keyword is permitted at this point. If the function returns true
78             then the keyword is consumed and parsed as per L.
79              
80             I is an opaque pointer which is passed through to each of the hook
81             stage functions when they are invoked.
82              
83             =head2 xs_parse_sublike_any
84              
85             int xs_parse_sublike_any(const struct XSParseSublikeHooks *hooks, void *hookdata,
86             OP **op_ptr)
87              
88             This function expects to consume an introduction keyword at the lexer position
89             which is either C or the name of another C-like keyword, which has
90             been previously registered using L. It then
91             proceeds to parse the subsequent syntax similar to how it would have parsed if
92             encountered by the module's own keyword parser plugin, except that the second
93             set of hooks given here also take effect.
94              
95             If a regular C is encountered, then this is parsed using the I in
96             a similar way to C.
97              
98             If a different registered C-like keyword is encountered, then parsing is
99             performed using B sets of hooks - the ones given to this function as
100             well as the ones registered with the keyword. This allows their effects to
101             combined. The hooks given by the I argument are considered to be on the
102             "outside" from those of the registered keyword "inside". The outside ones run
103             first for all stages, except C which runs them inside-out.
104              
105             I is an opaque pointer which is passed through to each of the hook
106             stage functions when they are invoked.
107              
108             Note that this function is now vaguely discouraged, in favour of using a
109             prefixing keyword instead, by using the C flag.
110              
111             =head2 xps_signature_add_param
112              
113             void xps_signature_add_param(struct XSParseSublikeContext *ctx,
114             struct XPSSignatureParamDetails *details);
115              
116             I
117              
118             This B function may only be called during the C
119             or C hook stages. It is used to insert extra signature
120             parameters, either at the beginning (when called by the start hook), or at the
121             end (when called by the finish hook). It takes details of the parameter to add
122             from an addressed structure, which has the following fields.
123              
124             struct XPSSignatureParamDetails {
125             U32 ver;
126              
127             char sigil;
128             PADOFFSET padix;
129             };
130              
131             The caller must set the I field equal to C.
132              
133             The I field gives the leading sigil of the parameter; C<$> for
134             mandatory scalars, C<@> or C<%> for a final slurpy. The I field gives
135             the pad offset for a pad variable to store the value into. The caller is
136             (currently) responsible for creating that pad variable.
137              
138             At the present version, this API cannot create optional, or named parameters.
139             These abilities may be added in a later version which expands on the
140             structure's definition to add new fields to support this.
141              
142             =head2 xps_signature_query_*
143              
144             IV xps_signature_query_params(struct XSParseSublikeContext *ctx);
145              
146             IV xps_signature_query_optparams(struct XSParseSublikeContext *ctx);
147              
148             char xps_signature_query_slurpy(struct XSParseSublikeContext *ctx);
149              
150             I
151              
152             These B functions may only be called during the
153             C or C hook stages. They are used to query
154             details about the accumulated set of signature parameters. The C<_params>
155             query returns the total number of defined parameters - counting all mandatory,
156             optional, and a final slurpy if present. C<_optparams> returns a count of only
157             the optional parameters. C<_slurpy> returns the sigil character of a final
158             slurpy parameter (C<@> or C<%>), or zero if no slurpy parameter is present.
159              
160             =head1 PARSE CONTEXT
161              
162             The various hook stages all share state about the ongoing parse process using
163             various fields of the C structure.
164              
165             struct XSParseSublikeContext {
166             SV *name;
167             OP *attrs;
168             OP *body;
169             CV *cv;
170             U32 actions;
171             HV *moddata;
172             }
173              
174             The C field will contain a bitmask of action flags that control the
175             various steps that C might take inbetween invoking hook
176             stages. The initial value of this field is set after the name-parsing stage,
177             depending on whether or not a name is found. Stage hook functions may modify
178             the field to adjust the subsequent behaviour.
179              
180             At the current ABI version, a module will have to set the
181             C bit of the C field in
182             order to make use of the I field. A future ABI version may remove
183             this restriction.
184              
185             =over 4
186              
187             =item XS_PARSE_SUBLIKE_ACTION_CVf_ANON
188              
189             If set, the C call will be set up for an anonymous function
190             protosub; if not it will be set for a named function. This is set by default
191             if a name was not found.
192              
193             =item XS_PARSE_SUBLIKE_ACTION_SET_CVNAME
194              
195             If set, the newly-constructed CV will have the given name set on it. This is
196             set by default if a name was found.
197              
198             On Perl versions 5.22 and above, this flag can be set even if
199             C is not. In this case, the CV will
200             not be reachable via the symbol table, even though it knows its own name and
201             pretends that it is. On earlier versions of perl this flag will be ignored in
202             that case.
203              
204             =item XS_PARSE_SUBLIKE_ACTION_INSTALL_SYMBOL
205              
206             If set, the newly-constructed CV will be installed into the symbol table at
207             its given name. Note that it is not possible to enable this flag without also
208             enabling C. This is set by default if a
209             name was found.
210              
211             =item XS_PARSE_SUBLIKE_ACTION_INSTALL_LEXICAL
212              
213             If set, the newly-constructed CV will be installed into the currently
214             compiling lexical pad as its given name. This is only available on Perl
215             version 5.18 or above, and conflicts with the alternative of
216             C. This is set by default if a name
217             was found I the C keyword appeared before the construction.
218              
219             =item XS_PARSE_SUBLIKE_ACTION_REFGEN_ANONCODE
220              
221             If set, the syntax will yield the C / C optree
222             fragment typical of anonymous code expressions; if not it will be C.
223             This is set by default if a name was not found.
224              
225             =item XS_PARSE_SUBLIKE_ACTION_RET_EXPR
226              
227             If set, the syntax will parse like an expression; if not it will parse like a
228             statement. This is set by default if a name was not found.
229              
230             =back
231              
232             The I field will point towards an HV that modules can used to store
233             extra data between stages. As a naming convention a module should prefix its
234             keys with its own module name and a slash character, C<"Some::Module/field">.
235             The field will point to a newly-created HV for every parse invocation, and
236             will be released when each parse is complete.
237              
238             =head1 PARSE HOOKS
239              
240             The C structure provides the following hook stages, which
241             are invoked in the given order.
242              
243             The structure has a I field, which controls various optional parts of
244             operation. The following flags are defined.
245              
246             =over 4
247              
248             =item XS_PARSE_SUBLIKE_FLAG_BODY_OPTIONAL
249              
250             If B set, the I field will imply the
251             C flag, making the body part required. By setting
252             this flag this will no longer happen. If all hooks agree, then the body will
253             become optional.
254              
255             =item XS_PARSE_SUBLIKE_FLAG_PREFIX
256              
257             If set, the keyword is considered to be a prefix that can be placed in front
258             of C or another sub-like keyword, to add its set of hooks in addition to
259             those of the following keyword. These prefices may be further stacked.
260              
261             =item XS_PARSE_SUBLIKE_FLAG_ALLOW_PKGNAME
262              
263             I
264              
265             If B set, then fully-qualified identifiers that include a package name
266             are not allowed when declaring a named function. If all hooks agree by all
267             setting the flag, then the name may be fully-qualified to add the
268             newly-declared function into a different package.
269              
270             =item XS_PARSE_SUBLIKE_FLAG_SIGNATURE_NAMED_PARAMS
271              
272             If set, use the extended signature parser of this module when parsing a
273             signature and additionally permit the use of named parameter syntax, as
274             documented in L.
275              
276             =item XS_PARSE_SUBLIKE_FLAG_SIGNATURE_PARAM_ATTRIBUTES
277              
278             If set, use the extended signature parser of this module when parsing a
279             signature and additionally permit the use of attribute declarations on
280             parameter variables, as documented in L.
281              
282             =item XS_PARSE_SUBLIKE_FLAG_SIGNATURE_REFALIAS
283              
284             If set, use the extended signature parser of this module when parsing a
285             signature and additionally permit the use of refalias parameter syntax, as
286             documented in L.
287              
288             =back
289              
290             In addition there are two C fields named I and
291             I which control the behaviour of various parts of the syntax which
292             are usually optional. Any parts with bits set in I become
293             non-optional, and an error if they are missing. Any parts with bits set in
294             I will skip the relevant part of the parsing process.
295              
296             When multiple sets of hooks are combined by the C
297             function, or as part of parsing prefixing keywords, these bitmasks are
298             accumulated together with inclusive or. Any part required by any set of hooks
299             will still be required; any step skipped by either will be skipped entirely.
300              
301             If the same bit is set in both fields then the relevant parsing step will not
302             be performed but it will still be an error for that section to be missing.
303             This is likely not useful.
304              
305             Note that for skipped parts, only the actual parsing steps are skipped. A hook
306             function can still set the relevant fields in the context structure anyway to
307             force a particular value for those parts.
308              
309             =over 4
310              
311             =item XS_PARSE_SUBLIKE_PART_NAME
312              
313             The name of the function.
314              
315             =item XS_PARSE_SUBLIKE_PART_ATTRS
316              
317             The attributes of the function.
318              
319             This part can be skipped, but the bit is ignored when in I. It
320             is always permitted to not provide any additional attributes to a function
321             definition.
322              
323             =item XS_PARSE_SUBLIKE_PART_SIGNATURE
324              
325             The parameter signature of the function.
326              
327             This part can be skipped, but it is always permitted not to provide a
328             signature for a function definition even if the bit it set in
329             I. This is because such syntax only applies when
330             C is in effect, and only on supporting perl
331             versions.
332              
333             However, setting the bit in I instead has the effect of
334             enabling C (at least on supporting perl versions),
335             thus permitting the syntax to use a signature even if the signatures feature
336             was not previously enabled.
337              
338             =item XS_PARSE_SUBLIKE_PART_BODY
339              
340             The actual body of the function, expressed as a brace-delimited block.
341              
342             This part cannot be skipped, but it can be made optional by omitting it from
343             the I field. Instead of the block, it is permitted to place a
344             single semicolon (C<;>) to act as a statement terminator; thus giving the same
345             syntax as a subroutine forward declaration.
346              
347             In this case, the C and C fields of the context structure will
348             remain C.
349              
350             This flag is currently implied on the I field if the hook does
351             not supply the C flag; meaning that most
352             use-cases will make it a required part.
353              
354             =back
355              
356             =head2 The C Stage
357              
358             const char *permit_hintkey
359             bool (*permit)(pTHX_ void *hookdata)
360              
361             Called by the installed keyword parser hook which is used to handle keywords
362             registered by L.
363              
364             As a shortcut for the common case, the C may point to a string
365             to look up from the hints hash. If the given key name is not found in the
366             hints hash then the keyword is not permitted. If the key is present then the
367             C function is invoked as normal.
368              
369             If not rejected by a hint key that was not found in the hints hash, the
370             function part of the stage is called next and should inspect whether the
371             keyword is permitted at this time perhaps by inspecting other lexical clues,
372             and return true only if the keyword is permitted.
373              
374             Both the string and the function are optional. Either or both may be present.
375             If neither is present then the keyword is always permitted - which is likely
376             not what you wanted to do.
377              
378             =head2 Parse Name
379              
380             At this point, the optional name is parsed and filled into the C field
381             of the context.
382              
383             =head2 The C Stage
384              
385             void (*pre_subparse)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
386              
387             Invoked just before C is called.
388              
389             =head2 Parse Attrs
390              
391             At this point the optional sub attributes are parsed and filled into the
392             C field of the context, then C is called.
393              
394             =head2 The C Stage
395              
396             bool (*filter_attr)(pTHX_ struct XSParseSublikeContext *ctx,
397             SV *attr, SV *val, void *hookdata);
398              
399             If this optional stage is defined, then each individual attribute is passed
400             through this optional filter function immediately as each is parsed. I
401             will be a string SV containing the name of the attribute, and I will
402             either be C, or a string SV containing the contents of the parens after
403             its name (without the parens themselves).
404              
405             If the filter returns C, it indicates that it has in some way handled
406             the attribute and it should not be added to the list given to C.
407             If the filter returns C it will be handled in the usual way; equivalent
408             to the case where the filter function did not exist.
409              
410             =head2 The C Stage
411              
412             void (*post_blockstart)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
413              
414             Invoked after the C function has been called. This hook stage
415             may wish to perform any alterations of C or related, inspect or
416             alter the lexical pad, provide hints hash values, or any other tasks before
417             the signature and code body are parsed.
418              
419             =head2 Parse Signature
420              
421             If the perl version supports subroutine signatures, and the feature is enabled
422             at this point, then an optional signatured is expected.
423              
424             I: if the open parenthesis of a signature declaration is
425             found, then the C stage is invoked. Once the signature has
426             been parsed, the C stage is invoked.
427              
428             void (*start_signature)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata);
429              
430             void (*finish_signature)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata);
431              
432             Code in either of these hook stages is permitted to call
433             L, or any of the C functions.
434              
435             =head2 Parse Body
436              
437             At this point, the main body of the function is parsed and the optree is
438             stored in the C field of the context. If a subroutine signature was
439             found, the body will be prefixed with the signature ops as well.
440              
441             =head2 The C Stage
442              
443             void (*pre_blockend)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
444              
445             Invoked just before the C function is invoked. The hook stage may
446             wish to inspect or alter the optree stored in the C context field.
447              
448             =head2 The C Stage
449              
450             void (*post_newcv)(pTHX_ struct XSParseSublikeContext *ctx, void *hookdata)
451              
452             Invoked just after C has been invoked on the optree. The hook
453             stage may wish to inspect or alter the CV stored in the C context field.
454              
455             =cut
456              
457             =head1 AUTHOR
458              
459             Paul Evans
460              
461             =cut
462              
463             0x55AA;