NAME XS::Parse::Keyword::FromPerl - drive XS::Parse::Keyword directly from Perl DESCRIPTION This module provides a Perl-visible API wrapping (some of) the functionality provided by XS::Parse::Keyword, allowing extension keywords to be added to the Perl language by writing code in Perl itself. It provides a thin wrapping later over the XS functions provided by XPK itself, and additionally provides some extra perl-visible functions for things like optree management, which would normally be written directly in C code. No real attempt is made here to provide further abstractions on top of the API already provided by Perl and XPK, so users will have to be familiar with the overall concepts there as well. This module is currently experimental, on top of the already-experimental nature of XS::Parse::Keyword itself. UTILITY FUNCTIONS The following helper functions are provided to allow Perl code to get access to various parts of the C-level API that would be useful when building optrees for keywords. They are not part of the XS::Parse::Keyword API. opcode $type = opcode( $opname ); Returns an opcode integer corresponding to the given op name, which should be lowercase and without the leading OP_... prefix. As this involves a linear search across the entire PL_op_name array you may wish to perform this just once and store the result, perhaps using use constant for convenience. use constant OP_CONST => opcode("const"); op_contextualize $op = op_contextualize( $op, $context ); Applies a syntactic context to an optree representing an expression. $context must be one of the exported constants G_VOID, G_SCALAR, or G_LIST. op_scope $op = op_scope( $op ); Wraps an optree with some additional ops so that a runtime dynamic scope will created. new*OP This family of functions return a new OP of the given class, for the type, flags, and other arguments specified. A suitable $type can be obtained by using the "opcode" function. $flags contains the opflags; a bitmask of the following constants. OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST OPf_KIDS OPf_PARENS OPf_REF OPf_MOD OPf_STACKED OPf_SPECIAL The op is returned as a B::OP instance or a subclass thereof. These functions can only be called during the build phase of a keyword hook, because they depend on having the correct context set by the currently-compiling function. newOP $op = newOP( $type, $flags ); Returns a new base OP for the given type and flags. newASSIGNOP $op = newASSIGNOP( $flags, $left, $optype, $right ); Returns a new op representing an assignment operation from the right to the left OP child of the given type. Note the odd order of arguments. newBINOP $op = newBINOP( $type, $flags, $first, $last ); Returns a new BINOP for the given type, flags, and first and last OP child. newCONDOP $op = newCONDOP( $flags, $first, $trueop, $falseop ); Returns a new conditional expression op for the given condition expression and true and false alternatives, all as OP instances. newFOROP $op = newFOROP( $flags, %svop, $expr, $block, $cont ); Returns a new optree representing a heavyweight for loop, given the optional iterator SV op, the list expression, the block, and the optional continue block, all as OP instances. newGVOP $op = newGVOP( $type, $flags, $gvref ); Returns a new SVOP for the given type, flags, and GV given by a GLOB reference. The referred-to GLOB will be stored in the SVOP itself. newLISTOP $op = newLISTOP( $type, $flags, @children ); Returns a new LISTOP for the given type, flags, and child SVs. Note that an arbitrary number of child SVs can be passed here. This wrapper function will automatically perform the op_convert_list conversion from a plain OP_LIST if required. newLOGOP $op = newLOGOP( $type, $flags, $first, $other ); Returns a new LOGOP for the given type, flags, and first and other OP child. newPADxVOP $op = newPADxVOP( $type, $flags, $padoffset ); Returns a new op for the given type, flags, and pad offset. $type must be one of OP_PADSV, OP_PADAV, OP_PADHV or OP_PADCV. newSVOP $op = newSVOP( $type, $flags, $sv ); Returns a new SVOP for the given type, flags, and SV. A copy of the given scalar will be stored in the SVOP itself. newUNOP $op = newUNOP( $type, $flags, $first ); Returns a new UNOP for the given type, flags, and first OP child. XPK FUNCTIONS register_xs_parse_keyword register_xs_parse_keyword "name" => %args; Registers a new extension keyword into the XS::Parse::Keyword registry, defined using the given name and arguments. Takes the following named arguments: flags => INT Optional. If present, a bitmask of the following flag constants: XPK_FLAG_EXPR The build phase is expected to return KEYWORD_PLUGIN_EXPR. XPK_FLAG_STMT The build phase is expected to return KEYWORD_PLUGIN_STMT. XPK_FLAG_AUTOSEMI The syntax forms a complete statement, which should be followed by ;. pieces => ARRAY Optional. If present, contains definitions for the syntax pieces to be parsed for the syntax of this keyword. This must be composed of a list of calls to the various XPK_... piece-generating functions; documented below. permit_hintkey => STRING Optional. A string value to use for the "permit_hintkey". permit => CODE Optional. Callback function for the "permit" phase of keyword parsing. $ok = $permit->( $hookdata ); When invoked, it is passed a single arugment containing the (optional) hookdata value, and its result should be a boolean scalar. At least one of permit_hintkey or permit must be provided. check => CODE Optional. Callback function for the "check" phase of keyword parsing. $check->( $hookdata ); When invoked, it is passsed a single argument containing the (optional) bookdata value. build => CODE Callback function for the "build" phase of keyword parsing. $ret = $build->( \$out, \@args, $hookdata ); When invoked, it is passed a SCALAR ref to store the output optree into, an ARRAY reference containing the parsed arguments, and the (optional) hookdata value. The @args array will contain object references referring to the individual arguments parsed by the parser pieces. See "Parser Arguments". The callback function should be build an optree as a B::OP fragment, possibly by calling the various new*OP() functions defined above, and store the eventual result into the scalar referred to by the first argument. The callback should return one of KEYWORD_PLUGIN_EXPR or KEYWORD_PLUGIN_STMT to indicate how its syntax should be interpreted by the perl parser. hookdata => SCALAR Optional. If present, this scalar value is stored by the keyword definition and passed into each of the phase callbacks when invoked. If not present then undef will be passed to the callbacks instead. Piece Type Functions The following functions can be used to generate parsing pieces. XPK_BLOCK A block of code, returned in the op field. XPK_ANONSUB An anonymous subroutine, returned in the cv field. XPK_ARITHEXPR An arithemetic expression, returned in the op field. XPK_TERMEXPR A term expression, returned in the op field. XPK_LISTEXPR A list expression, returned in the op field. XPK_IDENT, XPK_IDENT_OPT An identifier, returned as a string in the sv field. The _OPT variant is optional. XPK_PACKAGENAME, XPK_PACKAGENAME_OPT A package name, returned as a string in the sv field. The _OPT variant is optional. XPK_LEXVARNAME XPK_LEXVARNAME($kind) A lexical variable name, returned as a string in the sv field. The $kind must be a bitmask of XPK_LEXVAR_SCALAR, XPK_LEXVAR_ARRAY, XPK_LEXVAR_HASH; or XPK_LEXVAR_ANY for convenience to set all three. XPK_VSTRING, XPK_VSTRING_OPT A version string, returned as a version object instance in the sv field. The _OPT variant is optional. XPK_LEXVAR XPK_LEXVAR($kind) A lexical variable that already exists in the pad, returned as a pad offset in the padix field. $kind is specified as in XPK_LEXVARNAME. XPK_LEXVAR_MY XPK_LEXVAR_MY($kind) A lexical variable, parsed as if it appeared in a my expression. It will be added to the pad and returned as a pad offset in the padix field. XPK_COMMA XPK_COLON XPK_EQUALS A literal comma, colon or equals sign. These do not appear in the arguments list. XPK_LITERAL XPK_LISTEXPR($string) A literal string match. No value is returned. This should be avoided if at all possible, in favour of the character matches above, or XPK_KEYWORD. XPK_KEYWORD XPK_KEYWORD($string) A literal string match, which requires that the following text does not begin with an identifier character (thus avoiding prefix-match problems). No value is returned. XPK_SEQUENCE XPK_SEQUENCE(@pieces) A sub-sequence. Normally this is not necessary, as most of the structure-forming functions already take a sequence of pieces. It is mostly useful as as an option to the XPK_CHOICE function. Nothing extra is returned, beyond the values from the individual pieces. XPK_OPTIONAL XPK_OPTIONAL(@pieces) An optional sequence of pieces that may or may not be present. Returns an integer value in the i field of 0 if the sequence was not found, or 1 followed by its values if the sequence was found. XPK_REPEATED XPK_REPEATED(@pieces) A repeating sequence of pieces. Returns an integer value in the i field indicating how many times the sequence repeated, followed by all the values returned by each. XPK_CHOICE XPK_CHOICE(@pieces) The pieces of this function are not interpreted as a sequence, but instead as a list of possible choices. Returns an integer value in the i field indicating which choice was found, followed by all the values returned by that sequence. The first possible choice is numbered 0. If no choice matched, it returns -1. To cause an error instead, use XPK_FAILURE. XPK_FAILURE XPK_FAILURE($message) Attempting to parse this piece type will immediately cause a compile-time failure with the given message. This can be used as the final option in XPK_CHOICE to ensure a valid match. XPK_PARENSCOPE XPK_PARENSCOPE(@pieces) Expects to find a sequence of pieces, all surrounded by parentheses (round brackets, ( ... )). Nothing extra is returned, beyond the values from the individual contained pieces. XPK_ARGSCOPE XPK_ARGSCOPE(@pieces) A scope similar to XPK_PARENSCOPE except that the parentheses themselves are optional, similar to perl's parsing of calls to known functions. XPK_BRACKETSCOPE XPK_BRACKETSCOPE(@pieces) Expects to find a sequence of pieces, all surrounded by square brackets ([ ... ]). Nothing extra is returned, beyond the values from the individual contained pieces. XPK_BRACESCOPE XPK_BRACESCOPE(@pieces) Expects to find a sequence of pieces, all surrounded by braces ({ ... }). Nothing extra is returned, beyond the values from the individual contained pieces. XPK_CHEVRONSCOPE XPK_CHEVRONSCOPE(@pieces) Expects to find a sequence of pieces, all surrounded by chevrons (angle brackets, < ... >). Nothing extra is returned, beyond the values from the individual contained pieces. Parser Arguments Each of the values given in the @args array for the "build" phase callback are given as object references having the following methods op $op = $arg->op; Returns an optree. cv $cv = $arg->cv; Returns a CV wrapped in a CODE reference. sv $sv = $arg->sv; Returns the SV itself, or undef if the optional SV was absent. has_sv $ok = $arg->has_sv; Returns true if the optional SV was present (even if it was undef), or false if it was absent. i $i = $arg->i; Returns an integer. padix $padix = $arg->padix; Returns a pad offset index as an integer. line $line = $arg->line; Returns the line number of the source text on which the piece was started. TODO * More new*OP() wrapper functions. * More optree-mangling functions. At least, some way to set the TARG might be handy. AUTHOR Paul Evans