[Prev][Next][Index][Thread]
RE: Macro loops infinitely --- GD bug?
To cut to the chase, the easiest way to express this is probably:
define macro one-definer
{ define one ?:name ?once end }
=> { define constant ?name = list(?once) }
once:
{ } => { }
{ ?inner:*; ... } => { ?inner, ... }
inner:
{ } => { }
{ ?:expression, ... } => { ?expression, ... }
end macro;
There are a couple of reasons for the infinite recursions in the
other formulations. First, selection of a matching pattern within
a rule set is performed and committed to without consulting any
aux-rules referred to[*]. For example, if a macro contains:
rule:
{ ?subrule } => { something }
{ ?any:* } => { something else }
subrule:
{ ?:name } => { ?name }
the ?any:* pattern will never be reached. That's because:
{ ?subrule } => { something }
is actually just shorthand for:
{ ?subrule:* } => { something }
i.e. an unconstrained wildcard match followed by an aux-rule
transformation.
The safest way to think of aux-rules is as transformers applied
after pattern matching and before substitution. A match failure
in an aux-rule transformation won't cause backtracking within
the invoking rule set because at that point pattern matching is
a done deal in that rule set.
The shorthand that allows the constraint to be elided on a pattern
variable that names an aux-rule set has always been confusing and
I recommend that people don't use it. Always declare the wildcard
constraint explicitly.
The other thing that often comes as a surprise is just how many
cases a pattern like this is happy to match:
{ ?stuff:*; ... } => { something }
Between wildcarding and the implicit separator folding rules,
all of these inputs match (to at least one level):
// the empty fragment
1 // an input with no separator at all
1; // an input with a terminator
1; 2 // an input with a separator
That's why it's important to put unambiguous base cases (like the
empty patterns in the example) first within a rule set.
-- Keith
[*] Technically there's one exception to this to do with
"intermediate word" handling, but it's not something macro
writers have to worry about.
References: