summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/infix.tl8
-rw-r--r--txr.147
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)
diff --git a/txr.1 b/txr.1
index 3f5c79a0..1060f558 100644
--- a/txr.1
+++ b/txr.1
@@ -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"