The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

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

DESCRIPTION

This module provides some XS functions to assist in writing syntax modules that provide new infix operators as perl syntax, primarily for authors of syntax plugins. It is unlikely to be of much use to anyone else; and highly unlikely to be of any use when writing prl code using these. Unless you are writing a syntax plugin using XS, this module is not for you.

This module is also currently experimental, and the design is still evolving and subject to change. Later versions may break ABI compatibility, requiring changes or at least a rebuild of any module that depends on it.

In addition, the places this functionality can be used are relatively small. No current release of perl actually supports custom infix operators, though I have a branch where I am currently experimenting with such support:

https://github.com/leonerd/perl5/tree/infix-plugin

In addition, the various XPK_INFIX_* token types of XS::Parse::Keyword support querying on this module, so some syntax provided by other modules may be able to make use of these new infix operators.

CONSTANTS

HAVE_PL_INFIX_PLUGIN

   if( XS::Parse::Infix::HAVE_PL_INFIX_PLUGIN ) { ... }

This constant is true if built on a perl that supports the PL_infix_plugin extension mechanism, meaning that custom infix operators registered with this module will actually be recognised by the perl parser.

No actual production or development releases of perl yet support this feature, but see above for details of a branch which does.

XS FUNCTIONS

boot_xs_parse_infix

  void boot_xs_parse_infix(double ver);

Call this function from your BOOT section in order to initialise the module and parsing hooks.

ver should either be 0 or a decimal number for the module version requirement; e.g.

   boot_xs_parse_infix(0.14);

xs_parse_infix_new_op

   OP *xs_parse_infix_new_op(const struct XSParseInfixInfo *info, U32 flags,
      OP *lhs, OP *rhs);

This function constructs a new optree fragment to represent invoking the infix operator with the given operands. It should be used much the same as core perl's newBINOP function.

The info structure pointer would be obtained from the infix field of the result of invoking the various XPK_INFIX_* token types from XS::Parse::Keyword.

register_xs_parse_infix

   void register_xs_parse_infix(const char *opname,
      const struct XSParseInfixHooks *hooks, void *hookdata);

This function installs a set of parsing hooks to be associated with the given operator name. This new operator will then be available via XS::Parse::Keyword by the various XPK_INFIX_* token types, or to core perl's PL_infix_plugin if availble.

These tokens will all yield an info structure, with the following fields:

   struct XSParseInfixInfo {
      const char *opname;
      OPCODE opcode;  /* for built-in operators, or OP_CUSTOM for 
                         custom-registered ones */

      struct XSParseInfixHooks *hooks;
      void                     *hookdata;
   };

PARSE HOOKS

The XSParseInfixHooks structure provides the following fields which are used at various stages of parsing.

   struct XSParseInfixHooks {
      enum XSParseInfixClassification cls;

      const char *permit_hintkey;
      bool (*permit)(pTHX_ void *hookdata);

      OP *(*new_op)(pTHX_ U32 flags, OP *lhs, OP *rhs, void *hookdata);
      OP *(*ppaddr)(pTHX);
   };

The Selection Stage

The cls field gives a "classification" of the operator, suggesting what sort of operation it provides. This is used as a filter by the various XS::Parse::Keyword selection macros.

The classification should be one of the XPI_CLS_* constants found and described further in the main XSParseInfix.h file.

The permit Stage

As a shortcut for the common case, the permit_hintkey may point to a string to look up from the hints hash. If the given key name is not found in the hints hash then the keyword is not permitted. If the key is present then the permit function is invoked as normal.

If not rejected by a hint key that was not found in the hints hash, the function part of the stage is called next and should inspect whether the keyword is permitted at this time perhaps by inspecting other lexical clues, and return true only if the keyword is permitted.

Both the string and the function are optional. Either or both may be present. If neither is present then the keyword is always permitted - which is likely not what you wanted to do.

The Op Generation Stage

If the infix operator is going to be used, then one of the new_op or the ppaddr fields explain how to create a new optree fragment.

If 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 ppaddr will be used instead to construct a new BINOP of the OP_CUSTOM type.

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>