File: XSParseKeyword.h

package info (click to toggle)
libxs-parse-keyword-perl 0.49-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 572 kB
  • sloc: ansic: 2,037; perl: 1,013; sh: 6; makefile: 3
file content (320 lines) | stat: -rw-r--r-- 15,280 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
#ifndef __XS_PARSE_KEYWORD_H__
#define __XS_PARSE_KEYWORD_H__

#define XSPARSEKEYWORD_ABI_VERSION 2

struct XSParseKeywordPieceType;
struct XSParseKeywordPieceType {
  int type;
  union {
    char c;                                       /* LITERALCHAR */
    const char *str;                              /* LITERALSTR */
    const struct XSParseKeywordPieceType *pieces; /* containers */
    void (*callback)(pTHX_ void *hookdata);       /* SETUP, ANONSUB PREPARE+START */

    OP *(*op_wrap_callback)(pTHX_ OP *o, void *hookdata);
  } u;
};

enum {
  XPK_FLAG_EXPR           = (1<<0),
  XPK_FLAG_STMT           = (1<<1),
  XPK_FLAG_AUTOSEMI       = (1<<2),
  XPK_FLAG_BLOCKSCOPE     = (1<<3),
  XPK_FLAG_PERMIT_LEXICAL = (1<<4),
};

enum {
  /* skip zero */

  /*                                    emits */
  XS_PARSE_KEYWORD_LITERALCHAR = 1,   /* nothing */
  XS_PARSE_KEYWORD_LITERALSTR,        /* nothing */
  XS_PARSE_KEYWORD_AUTOSEMI,          /* nothing */
  XS_PARSE_KEYWORD_WARNING = 0x0e,    /* nothing */
  XS_PARSE_KEYWORD_FAILURE,           /* nothing */

  XS_PARSE_KEYWORD_BLOCK = 0x10,      /* op */
  XS_PARSE_KEYWORD_ANONSUB,           /* cv */
  XS_PARSE_KEYWORD_ARITHEXPR,         /* op */
  XS_PARSE_KEYWORD_TERMEXPR,          /* op */
  XS_PARSE_KEYWORD_LISTEXPR,          /* op */
  /* TODO: XS_PARSE_KEYWORD_FULLEXPR = 0x15 */
  XS_PARSE_KEYWORD_IDENT = 0x16,      /* sv */
  XS_PARSE_KEYWORD_PACKAGENAME,       /* sv */
  XS_PARSE_KEYWORD_LEXVARNAME,        /* sv */
  XS_PARSE_KEYWORD_LEXVAR,            /* padix */
  XS_PARSE_KEYWORD_ATTRS,             /* i / {attr.name + attr.val} */
  XS_PARSE_KEYWORD_VSTRING,           /* sv */

  XS_PARSE_KEYWORD_INFIX = 0x40,      /* infix */

  XS_PARSE_KEYWORD_INTRO_MY = 0x60,   /* emits nothing */

  XS_PARSE_KEYWORD_SETUP = 0x70,      /* invokes callback, emits nothing */

  XS_PARSE_KEYWORD_ANONSUB_PREPARE,   /* invokes callback, emits nothing */
  XS_PARSE_KEYWORD_ANONSUB_START,     /* invokes callback, emits nothing */
  XS_PARSE_KEYWORD_ANONSUB_END,       /* invokes op_wrap_callback, emits nothing */
  XS_PARSE_KEYWORD_ANONSUB_WRAP,      /* invokes op_wrap_callback, emits nothing */

  XS_PARSE_KEYWORD_SEQUENCE = 0x80,   /* contained */
  XS_PARSE_KEYWORD_REPEATED,          /* i, contained */
  XS_PARSE_KEYWORD_CHOICE,            /* i, contained */
  XS_PARSE_KEYWORD_TAGGEDCHOICE,      /* i, contained */
  XS_PARSE_KEYWORD_SEPARATEDLIST,     /* i, contained */
  XS_PARSE_KEYWORD_PARENS = 0xb0,     /* contained */
  XS_PARSE_KEYWORD_BRACKETS,          /* contained */
  XS_PARSE_KEYWORD_BRACES,            /* contained */
  XS_PARSE_KEYWORD_CHEVRONS,          /* contained */
};

enum {
  XPK_LEXVAR_SCALAR = (1<<0),
  XPK_LEXVAR_ARRAY  = (1<<1),
  XPK_LEXVAR_HASH   = (1<<2),
  XPK_LEXVAR_ANY    = XPK_LEXVAR_SCALAR|XPK_LEXVAR_ARRAY|XPK_LEXVAR_HASH,
};

enum {
  XPK_TYPEFLAG_OPT      = (1<<16),
  XPK_TYPEFLAG_SPECIAL  = (1<<17), /* on XPK_LITERALSTR: keyword
                                      on XPK_BLOCK: scoped
                                      on XPK_LEXVAR: my */

  /* These three are shifted versions of perl's G_VOID, G_SCALAR, G_LIST */
  XPK_TYPEFLAG_G_VOID   = (1<<18),
  XPK_TYPEFLAG_G_SCALAR = (2<<18),
  XPK_TYPEFLAG_G_LIST   = (3<<18),

  XPK_TYPEFLAG_ENTERLEAVE = (1<<20), /* wrap ENTER/LEAVE pair around the item */

  XPK_TYPEFLAG_MAYBEPARENS = (1<<21), /* parens themselves are optional on PARENS */
};

#define XPK_PREFIXED(typecode,...) \
  {.type = typecode, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

#define XPK_BLOCK_flags(flags) {.type = XS_PARSE_KEYWORD_BLOCK|(flags), .u.pieces = NULL}
#define XPK_BLOCK              XPK_BLOCK_flags(0)
#define XPK_BLOCK_VOIDCTX      XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_VOID)
#define XPK_BLOCK_SCALARCTX    XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_SCALAR)
#define XPK_BLOCK_LISTCTX      XPK_BLOCK_flags(XPK_TYPEFLAG_SPECIAL|XPK_TYPEFLAG_G_LIST)

#define XPK_PREFIXED_BLOCK(...)            XPK_PREFIXED(XS_PARSE_KEYWORD_BLOCK, __VA_ARGS__)
#define XPK_PREFIXED_BLOCK_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_BLOCK|XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__)

#define XPK_SETUP(setup)       {.type = XS_PARSE_KEYWORD_SETUP, .u.callback = setup}

#define XPK_ANONSUB {.type = XS_PARSE_KEYWORD_ANONSUB}

#define XPK_ANONSUB_PREPARE(func)  {.type = XS_PARSE_KEYWORD_ANONSUB_PREPARE, .u.callback = func}
#define XPK_ANONSUB_START(func)    {.type = XS_PARSE_KEYWORD_ANONSUB_START, .u.callback = func}
#define XPK_ANONSUB_END(func)      {.type = XS_PARSE_KEYWORD_ANONSUB_END, .u.op_wrap_callback = func}
#define XPK_ANONSUB_WRAP(func)     {.type = XS_PARSE_KEYWORD_ANONSUB_WRAP, .u.op_wrap_callback = func}

#define XPK_STAGED_ANONSUB(...) \
  {.type = XS_PARSE_KEYWORD_ANONSUB, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

#define XPK_ARITHEXPR_flags(flags)  {.type = XS_PARSE_KEYWORD_ARITHEXPR|(flags)}
#define XPK_ARITHEXPR               XPK_ARITHEXPR_flags(0)
#define XPK_ARITHEXPR_VOIDCTX       XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_VOID)
#define XPK_ARITHEXPR_SCALARCTX     XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR)
#define XPK_ARITHEXPR_OPT           XPK_ARITHEXPR_flags(XPK_TYPEFLAG_OPT)
#define XPK_ARITHEXPR_VOIDCTX_OPT   XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT)
#define XPK_ARITHEXPR_SCALARCTX_OPT XPK_ARITHEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT)

#define XPK_TERMEXPR_flags(flags)  {.type = XS_PARSE_KEYWORD_TERMEXPR|(flags)}
#define XPK_TERMEXPR               XPK_TERMEXPR_flags(0)
#define XPK_TERMEXPR_VOIDCTX       XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID)
#define XPK_TERMEXPR_SCALARCTX     XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR)
#define XPK_TERMEXPR_OPT           XPK_TERMEXPR_flags(XPK_TYPEFLAG_OPT)
#define XPK_TERMEXPR_VOIDCTX_OPT   XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_VOID|XPK_TYPEFLAG_OPT)
#define XPK_TERMEXPR_SCALARCTX_OPT XPK_TERMEXPR_flags(XPK_TYPEFLAG_G_SCALAR|XPK_TYPEFLAG_OPT)

#define XPK_PREFIXED_TERMEXPR_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_TERMEXPR|XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__)

#define XPK_LISTEXPR_flags(flags) {.type = XS_PARSE_KEYWORD_LISTEXPR|(flags)}
#define XPK_LISTEXPR              XPK_LISTEXPR_flags(0)
#define XPK_LISTEXPR_LISTCTX      XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST)
#define XPK_LISTEXPR_OPT          XPK_LISTEXPR_flags(XPK_TYPEFLAG_OPT)
#define XPK_LISTEXPR_LISTCTX_OPT  XPK_LISTEXPR_flags(XPK_TYPEFLAG_G_LIST|XPK_TYPEFLAG_OPT)

#define XPK_PREFIXED_LISTEXPR_ENTERLEAVE(...) XPK_PREFIXED(XS_PARSE_KEYWORD_LISTEXPR|XPK_TYPEFLAG_ENTERLEAVE, __VA_ARGS__)

#define XPK_IDENT           {.type = XS_PARSE_KEYWORD_IDENT                       }
#define XPK_IDENT_OPT       {.type = XS_PARSE_KEYWORD_IDENT      |XPK_TYPEFLAG_OPT}
#define XPK_PACKAGENAME     {.type = XS_PARSE_KEYWORD_PACKAGENAME                 }
#define XPK_PACKAGENAME_OPT {.type = XS_PARSE_KEYWORD_PACKAGENAME|XPK_TYPEFLAG_OPT}

#define XPK_LEXVARNAME(kind) {.type = XS_PARSE_KEYWORD_LEXVARNAME, .u.c = kind}

#define XPK_LEXVAR(kind)    {.type = XS_PARSE_KEYWORD_LEXVAR, .u.c = kind}
#define XPK_LEXVAR_MY(kind) {.type = XS_PARSE_KEYWORD_LEXVAR|XPK_TYPEFLAG_SPECIAL, .u.c = kind}

#define XPK_ATTRIBUTES {.type = XS_PARSE_KEYWORD_ATTRS}

#define XPK_VSTRING     {.type = XS_PARSE_KEYWORD_VSTRING}
#define XPK_VSTRING_OPT {.type = XS_PARSE_KEYWORD_VSTRING|XPK_TYPEFLAG_OPT}

#define XPK_COMMA  {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','}
#define XPK_COLON  {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ':'}
#define XPK_EQUALS {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = '='}

#define XPK_LITERAL(s) {.type = XS_PARSE_KEYWORD_LITERALSTR, .u.str = (const char *)s}
#define XPK_STRING(s)  XPK_LITERAL(s)
#define XPK_AUTOSEMI   {.type = XS_PARSE_KEYWORD_AUTOSEMI}
#define XPK_KEYWORD(s) {.type = XS_PARSE_KEYWORD_LITERALSTR|XPK_TYPEFLAG_SPECIAL, .u.str = (const char *)s}

#define XPK_INFIX(select) {.type = XS_PARSE_KEYWORD_INFIX, .u.c = select}
#define XPK_INFIX_RELATION       XPK_INFIX(XPI_SELECT_RELATION)
#define XPK_INFIX_EQUALITY       XPK_INFIX(XPI_SELECT_EQUALITY)
#define XPK_INFIX_MATCH_NOSMART  XPK_INFIX(XPI_SELECT_MATCH_NOSMART)
#define XPK_INFIX_MATCH_SMART    XPK_INFIX(XPI_SELECT_MATCH_SMART)

#define XPK_INTRO_MY           {.type = XS_PARSE_KEYWORD_INTRO_MY}

#define XPK_SEQUENCE_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE, .u.pieces = p}
#define XPK_SEQUENCE(...)      XPK_SEQUENCE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))

/* First piece of these must be something probe-able */
#define XPK_OPTIONAL_pieces(p) {.type = XS_PARSE_KEYWORD_SEQUENCE|XPK_TYPEFLAG_OPT, .u.pieces = p}
#define XPK_OPTIONAL(...)      XPK_OPTIONAL_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))

#define XPK_REPEATED_pieces(p) {.type = XS_PARSE_KEYWORD_REPEATED, .u.pieces = p}
#define XPK_REPEATED(...)      XPK_REPEATED_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))

/* Every piece must be probeable */
#define XPK_CHOICE_pieces(p)  {.type = XS_PARSE_KEYWORD_CHOICE, .u.pieces = p}
#define XPK_CHOICE(...)       XPK_CHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))

/* Every piece must be probeable, and followed by XPK_TAG */
#define XPK_TAGGEDCHOICE_pieces(p) {.type = XS_PARSE_KEYWORD_TAGGEDCHOICE, .u.pieces = p}
#define XPK_TAGGEDCHOICE(...)      XPK_TAGGEDCHOICE_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0}, {0} }))
#define XPK_TAG(val) {.type = val}

#define XPK_COMMALIST(...) \
  {.type = XS_PARSE_KEYWORD_SEPARATEDLIST, .u.pieces = (const struct XSParseKeywordPieceType []){ \
      {.type = XS_PARSE_KEYWORD_LITERALCHAR, .u.c = ','}, __VA_ARGS__, {0}}}

#define XPK_WARNING_bit(bit,s)   {.type = (XS_PARSE_KEYWORD_WARNING|(bit << 24)), .u.str = (const char *)s}
#define XPK_WARNING(s)               XPK_WARNING_bit(0,s)
#define XPK_WARNING_AMBIGUOUS(s)     XPK_WARNING_bit(WARN_AMBIGUOUS,   s)
#define XPK_WARNING_DEPRECATED(s)    XPK_WARNING_bit(WARN_DEPRECATED,  s)
#define XPK_WARNING_EXPERIMENTAL(s)  XPK_WARNING_bit(WARN_EXPERIMENTAL,s)
#define XPK_WARNING_PRECEDENCE(s)    XPK_WARNING_bit(WARN_PRECEDENCE,  s)
#define XPK_WARNING_SYNTAX(s)        XPK_WARNING_bit(WARN_SYNTAX,      s)

#define XPK_FAILURE(s) {.type = XS_PARSE_KEYWORD_FAILURE, .u.str = (const char *)s}

#define XPK_PARENS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS, .u.pieces = p}
#define XPK_PARENS(...)      XPK_PARENS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))
#define XPK_PARENS_OPT(...) \
  {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

#define XPK_ARGS_pieces(p) {.type = XS_PARSE_KEYWORD_PARENS|XPK_TYPEFLAG_MAYBEPARENS, .u.pieces = p}
#define XPK_ARGS(...)      XPK_ARGS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))

#define XPK_BRACKETS_pieces(p) {.type = XS_PARSE_KEYWORD_BRACKETS, .u.pieces = p}
#define XPK_BRACKETS(...)      XPK_BRACKETS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))
#define XPK_BRACKETS_OPT(...) \
  {.type = XS_PARSE_KEYWORD_BRACKETS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

#define XPK_BRACES_pieces(p) {.type = XS_PARSE_KEYWORD_BRACES, .u.pieces = p}
#define XPK_BRACES(...)      XPK_BRACES_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))
#define XPK_BRACES_OPT(...) \
  {.type = XS_PARSE_KEYWORD_BRACES|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

#define XPK_CHEVRONS_pieces(p) {.type = XS_PARSE_KEYWORD_CHEVRONS, .u.pieces = p}
#define XPK_CHEVRONS(...)      XPK_CHEVRONS_pieces(((const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }))
#define XPK_CHEVRONS_OPT(...) \
  {.type = XS_PARSE_KEYWORD_CHEVRONS|XPK_TYPEFLAG_OPT, .u.pieces = (const struct XSParseKeywordPieceType []){ __VA_ARGS__, {0} }}

/* back-compat for older names */
#define XPK_PARENSCOPE_pieces    XPK_PARENS_pieces
#define XPK_PARENSCOPE           XPK_PARENS
#define XPK_PARENSCOPE_OPT       XPK_PARENS_OPT
#define XPK_ARGSCOPE_pieces      XPK_ARGS_pieces
#define XPK_ARGSCOPE             XPK_ARGS
#define XPK_BRACKETSCOPE_pieces  XPK_BRACKETS_pieces
#define XPK_BRACKETSCOPE         XPK_BRACKETS
#define XPK_BRACKETSCOPE_OPT     XPK_BRACKETS_OPT
#define XPK_BRACESCOPE_pieces    XPK_BRACES_pieces
#define XPK_BRACESCOPE           XPK_BRACES
#define XPK_BRACESCOPE_OPT       XPK_BRACES_OPT
#define XPK_CHEVRONSCOPE_pieces  XPK_CHEVRONS_pieces
#define XPK_CHEVRONSCOPE         XPK_CHEVRONS
#define XPK_CHEVRONSCOPE_OPT     XPK_CHEVRONS_OPT

/* This type defined in XSParseInfix.h */
typedef struct XSParseInfixInfo XSParseInfixInfo;

typedef struct {
  union {
    OP *op;
    CV *cv;
    SV *sv;
    int i;
    struct { SV *name; SV *value; } attr;
    PADOFFSET padix;
    XSParseInfixInfo *infix;
  };
  int line;
} XSParseKeywordPiece;

struct XSParseKeywordHooks {
  U32 flags;

  /* used by build1 */
  struct XSParseKeywordPieceType piece1;
  /* alternatively, used by build */
  const struct XSParseKeywordPieceType *pieces;

  /* These two hooks are ANDed together; both must pass, if present */
  const char *permit_hintkey;
  bool (*permit) (pTHX_ void *hookdata);

  void (*check)(pTHX_ void *hookdata);

  /* These are alternatives; the first one defined is used */
  int (*parse)(pTHX_ OP **opp, void *hookdata);
  int (*build)(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata);
  int (*build1)(pTHX_ OP **out, XSParseKeywordPiece *arg0, void *hookdata);
};

static void (*register_xs_parse_keyword_func)(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata);
#define register_xs_parse_keyword(kwname, hooks, hookdata)  S_register_xs_parse_keyword(aTHX_ kwname, hooks, hookdata)
static void S_register_xs_parse_keyword(pTHX_ const char *kwname, const struct XSParseKeywordHooks *hooks, void *hookdata)
{
  if(!register_xs_parse_keyword_func)
    croak("Must call boot_xs_parse_keyword() first");

  (*register_xs_parse_keyword_func)(aTHX_ kwname, hooks, hookdata);
}

#define boot_xs_parse_keyword(ver) S_boot_xs_parse_keyword(aTHX_ ver)
static void S_boot_xs_parse_keyword(pTHX_ double ver) {
  SV **svp;
  SV *versv = ver ? newSVnv(ver) : NULL;

  load_module(PERL_LOADMOD_NOIMPORT, newSVpvs("XS::Parse::Keyword"), versv, NULL);

  svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MIN", 0);
  if(!svp)
    croak("XS::Parse::Keyword ABI minimum version missing");
  int abi_ver = SvIV(*svp);
  if(abi_ver > XSPARSEKEYWORD_ABI_VERSION)
    croak("XS::Parse::Keyword ABI version mismatch - library supports >= %d, compiled for %d",
        abi_ver, XSPARSEKEYWORD_ABI_VERSION);

  svp = hv_fetchs(PL_modglobal, "XS::Parse::Keyword/ABIVERSION_MAX", 0);
  abi_ver = SvIV(*svp);
  if(abi_ver < XSPARSEKEYWORD_ABI_VERSION)
    croak("XS::Parse::Keyword ABI version mismatch - library supports <= %d, compiled for %d",
        abi_ver, XSPARSEKEYWORD_ABI_VERSION);

  register_xs_parse_keyword_func = INT2PTR(void (*)(pTHX_ const char *, const struct XSParseKeywordHooks *, void *),
      SvUV(*hv_fetchs(PL_modglobal, "XS::Parse::Keyword/register()@2", 0)));
}

#endif