diff options
-rw-r--r-- | stdlib/infix.tl | 8 | ||||
-rw-r--r-- | txr.1 | 47 |
2 files changed, 42 insertions, 13 deletions
diff --git a/stdlib/infix.tl b/stdlib/infix.tl index ef27ca41..88c42e2d 100644 --- a/stdlib/infix.tl +++ b/stdlib/infix.tl @@ -278,7 +278,13 @@ (let ((rexp (infix-expand-hook rest env nil))) (if (eq rexp rest) ^(,y ,x ,*rest) - ^(,y ,x ,rexp)))))) + ^(,y ,x ,rexp)))) + (@(require (@x . @rest) + (and rest (cdr rest) (funp env x))) + (let ((rexp (infix-expand-hook rest env nil))) + (if (eq rexp rest) + exp + ^(,x ,rexp)))))) (exp))) (defmacro usr:ifx (. body) @@ -54223,7 +54223,7 @@ Additionally, the symbols and .codn !f , indicate a prefix operator which, respectively, is and is not, -the name of a gobal or lexical functionl. +the name of a global or lexical function. The patterns which indicate a form for processing via .code parse-infix are: @@ -54409,23 +54409,36 @@ into .codn "(+ i 1)" . A form not falling into any of the above rules is recognized as "phony infix" -if: it consists of at least two elements, where the first element is not +if it conforms to one of two situations: +.RS +.IP 1. +It consists of at least two elements, where the first element is not a function, and the second element is a function. Both the lexical and global function namespaces are considered. -When a form is thus recognized, -it is transformed by exchanging the first and second positions. -Furthermore, if there are additional arguments after these two positions, they are -taken as an independent expression which is passed through the infix expansion -hook. If it is transformed by the hook, then the transformed expression -is taken as a single argument added to the two leading arguments -that have been exchanged. Otherwise, all the original untransformed -arguments are added. +When a form is thus recognized, it is transformed by exchanging the first and +second positions. Additionally, the remaining arguments may be transformed +as described below. +.IP 2. +It consists of at least two elements, where the first element is a function. +In this situation, the remaining arguments may be transformed as described +below. In this second situation, if no argument transformation takes place, +then the form is not recognized as "phony infix". +.RE +In either of the above two cases, additional elements after the function +symbol (the third and subsequent form elements in case 1, or second and +subsequent elements in case 2) are taken as an independent expression which is +passed through the infix expansion hook. If it is transformed by the hook, then +the transformed expression is taken as a single element which replaces +all of the original elements. Otherwise, all the original +untransformed arguments remain as-is, in which case, in situation 2 +it means that the expression remains untransformed, implying that it has +not been recognized as infix. This is a fallback strategy applied by the .code ifx macro's expander hook. If an expression isn't recognized as infix -by the above two rules, it is tried as a phony infix expression. -In spite of +by the auto-detection rules, it is tried as a phony infix expression via +one of the above two cases. Thus, in spite of .code cons not being registered as an infix operator, .code "(a cons b)" @@ -54448,6 +54461,16 @@ isn't recognized infix; so these elements remain as individual arguments, such that the expression transforms into .codn "(list a b c d)" . +According to the phony infix case 2 above, an expression like +.code "(list 2 + 2)" +transforms to +.codn "(list (+ 2 2))" ; +in other words, the arguments after the function are treated in the +same manner as for the expression +.codn "(1 list 2 + 2)" , +which is transformed to +.codn "(list 1 (+ 2 2))" . + Only compound expressions are recognized as infix. A sequence of atoms like .code "a * b" |