# A set of rules for parsing Signatures in perl6 # XXX no support for isLValue, isWritable, or isLazy (don't understand isLazy) # described in InternalNames.hs line 798 # ??? does (terminates => *) work with any named rule? # Can I do ',')>? # What about [ ](terminates => *) grammar Signature { # XXX add unicode alternatives token open_q { <[<]> } token close_q { <[>]> } token open_qq { <[<]**{2}> } # ??? is this syntax right? token close_qq { <[>]**{2}> } token open_paren { <[(]> } token close_paren { <[)]> } token open_curly { <[{]> } token close_curly { <[}]> } token open_array { <[[]> } token close_array { <[\]]> } # stand-in for bracketing constructs # XXX add more or get unicode character classes working # XXX after matching an open_group symbol, only count the # appropriate close_group as a match token open_group { [ | | | | | ] } token close_group { [ | | | | | ] } token close_param { <[,)]> } # separator used in multi sigs to separate multiple levels of invocants token tie_break { <[:]> } # perl6 sigils in signatures token is_array { $ := <[@]> } token is_scalar { $ := <[$]> } token is_code { $ := <[&]> } token is_hash { $ := <[%]> } token sigil { | | | } # names don't have \d as the first character and have # at least one non-_ character token param_name { [ | _ ]+ [ | \d | _ ]+ } token internal { } token external { } # defaults for arguments can be assigned in the sig token default { = ? $ := ',' )> } # types start with an uppercase letter token type_name { + [ | _ | \d ]* } token type { } token ret_type { } token type_var { } token ret_arrow { \-\-\> } token returns { * } # parse *@x and :$x and mark for slurpy/named token is_named { <[:]> } token is_slurpy { <[*]> } token prefix_mod { [ | ] } # parse $x! and $x? and mark for required/optional token is_optional { <[?]> } token is_required { <[!]> } token postfix_mod { [ | ] } # parse $^x and mark it as an implicit. leave room for other twigils token is_implicit { <[^]> } token twigil { } # traits have the same rules for names as params token trait_name := param_name; token trait { is + } # this allows specifying a type on a parameter, as well parameterizing that type. token dwigil { [:]**{2} } token declarator { my | our | has | state | constant } token type_param { + [ * ]? } # $x, $^x, $ token positional { [ ? $ := ? ] } # :$x, :x($y), :$, :$(x) token named { [ | $ := ? | ? ] } # *@x token slurpy { ? ? ? * ? } # [ $x, *@y ] # ??? how should unpacked params be accessed? in $? # in some cases they'll be aliased to something in $ # in other cases, they'll act as anonymous $ token unpacked { * ? ? + * * * } rule param { ? ? [ | | | ] ? * ? } # signature for a single dispatch routine # ??? does this definition backtrack rule single_sig { [ ? ]* * ? } # sig for multi dispatch routine rule multi_sig { [ ]* ? : { @single_sig[ *..( +$ - 1 ) ] >>++ } # thanks audreyt++ } }