David Whipp wrote: > But can I use a non-constant date? You didn't show us the iso_date rule.
> Obviously we could put the onus on the module writer to write super-flexible > rules/grammars. But will there be an easy way to force interpolative context > onto this type of regex-valued subroutine arg? With this rule you need literal numbers: rule iso_date { $year:=(\d{4}) - $month:=(\d{2}) - $day:=(\d{2}) } This rule is more flexible: rule iso_date { (<Perl.term>) - { let $year := eval $1 } (<Perl.term>) - { let $month := eval $2 } (<Perl.term>) { let $day := eval $3 } <($year =~ /^\d{4}$/ && $month =~ /^\d{2}$/ && $day =~ /^\d{2}$/)> } The eval is very restrictive though -- it forces the terms to have values at compile time and breaks lexical scoping. (Unless eval can play games with %MY and somehow evaluate in the caller's scope. Maybe caller.{MY}.eval?) We can tidy that up a little with another rule: rule value { <Perl.term> { let $0 := caller(2).{MY}.eval($term) } } rule iso_date { $year:=<value> - $month:=<value> - $day:=<value> <($year =~ /^\d{4}$/ && $month =~ /^\d{2}$/ && $day =~ /^\d{2}$/)> } There's still the compile-time value problem though. What is really needed is something that converts the date syntax to normal Perl code: rule iso_date { (<Perl.term>) - (<Perl.term>) - (<Perl.term>) { use grammar Perl::AbstractSyntax; $0 := (expr (invoke 'new (class 'Date) $1 $2 $3))) } This rule just generates code -- the $0 return result is spliced into the syntax tree at compile time. All the valid value checking is done at run-time in the Date object constructor. (Or maybe at compile time if the compiler can figure out there aren't any side-effects and the object is serializable. But that's a whole different thread.) It's very efficient because it only parses the source code once. All the compiler optimizations (like constant folding) get applied to your special syntax. But you're writing Parrot macros (IMCC on steroids maybe?) and not Perl! Another approach is to delay the final parse until run-time. In this case, the compiler runs the rule over the input source code and records the matched text, but without running any of the code blocks. When the sub is called at run-time, the matched text is parsed by the rule again, but this time with the code blocks enabled. The second rule above (using eval) would work fine this way (as long as the %MY games are possible). The down-side to this approach is that you have lots of string evals happening at run-time. Maybe all of these techniques will be possible? rule x is macro { ... } rule y is delayed { ... } rule z is syntax { ... } - Ken