Extended idiom recognition
This page applies to Harlequin v13.1r0 and later; both Harlequin Core and Harlequin MultiRIP.
PostScript Language Level 3 idiom substitution works by replacing a procedure (the template procedure). The template procedure is specified as the first element of an array supplied as the value of an entry in an Idiom Set, with a procedure (the substitute procedure, presumably equivalent at least in its operands and results) specified as the second element of the array. The attempt to match is done in the bind
operator.
The RIP extends this in two respects.
1. If any of the following names are present in the template procedure, they are treated as “wildcards”. That is, instead of matching against exactly the same name in the candidate for replacement, any value appropriate to the wildcard will match the template.
/integertype | Any integer. |
/realtype | Any real number or any integer. |
/booleantype | Any Boolean value, or the literal names |
/arraytype | Any executable array (procedure) such that the elements are only integers, reals, or strings (or any mixture of these). |
/stringtype, /dicttype, /filetype, /gstatetype, /nametype | Any object of the corresponding type. |
2. The idiom array may have a third entry. When this is present, the entry is a procedure that is responsible for constructing a replacement procedure dynamically.
The constructor procedure receives as operands the following items. (It will typically use only a subset of these and pop
the rest.)
- The matched procedure.
- The values of the matched wildcards, in the order they are encountered in the depth-first matching of the procedure.
- The number of wildcard matches.
- The template procedure.
- The substitute procedure.
The constructor removes all these operands and returns the substitute procedure that should be used instead of the fixed substitute given in the array.
For example, consider an idiom set array as follows. The purpose of the replacement is to return an array in which the elements are subtracted from 1 rather than being negated.
[ { [ /arraytype { neg } forall ] }
{} % unused fixed substitute
{
pop pop pop exch pop
[ exch { 1 exch sub } /forall load ] cvx
}
]
Then, if presented with:
{ { .3 .2 .4 } { neg } forall } bind
the idiom would be recognized and replaced with:
{ { .3 .2 .4 } { 1 -exch- -sub-} -forall- }
(where -x- implies the resolved operator referred to by the name x).