summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-04-21 09:46:54 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-04-21 09:46:54 -0700
commitb296d0a20eabd9ea19bd66d9a822452fce8038e9 (patch)
treeb8f03daa78f50fba1bf3eef6b21b20505dfe493f
parent787b60b4ed56e7805fd0bb5c9b3a450cc850ac9c (diff)
downloadtxr-b296d0a20eabd9ea19bd66d9a822452fce8038e9.tar.gz
txr-b296d0a20eabd9ea19bd66d9a822452fce8038e9.tar.bz2
txr-b296d0a20eabd9ea19bd66d9a822452fce8038e9.zip
infix: phony infix: try arguments as infix.
* stdlib/infix.tl (infix-expand-hook): In the phony infix logic that swaps the first two arguments, we also try the remaining arguments as a stand-alone expression, passing that through the hook. If the hook recognizes and transforms them as infix, we keep the result as one argument. Otherwise, we just take the original arguments. I already committed some test cases for this which are failing. * txr.1: Documented.
-rw-r--r--stdlib/infix.tl5
-rw-r--r--txr.134
2 files changed, 32 insertions, 7 deletions
diff --git a/stdlib/infix.tl b/stdlib/infix.tl
index 1469e1e7..6a19f957 100644
--- a/stdlib/infix.tl
+++ b/stdlib/infix.tl
@@ -255,7 +255,10 @@
tok)
(@(require (@x @y . @rest)
(and (not (fboundp x)) (fboundp y)))
- ^(,y ,x ,*rest))))
+ (let ((rexp (infix-expand-hook rest env nil)))
+ (if (eq rexp rest)
+ ^(,y ,x ,*rest)
+ ^(,y ,x ,rexp))))))
(exp)))
(defmacro usr:ifx (. body)
diff --git a/txr.1 b/txr.1
index e0819658..52c3c207 100644
--- a/txr.1
+++ b/txr.1
@@ -54367,17 +54367,39 @@ function, but the second element
.B is
an object satisfying that function. When a form is thus recognized,
it is transformed by exchanging the first and second position.
+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.
+
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.
-Phony infix allows expressions like
-.code "(a cons b)"
-to be transformed to
-.code "(cons a b)"
-in spite of the
+In spite of
.code cons
-function not being registered as an infix operator.
+not being registered as an infix operator,
+.code "(a cons b)"
+is transformed into
+.codn "(cons a b)" .
+Furthermore, the expression
+.code "(a cons c + d)"
+is transformed into
+.code "(cons a (+ c d))"
+due to the additional rule that the arguments
+.code "(c + d)"
+are recognized as an infix expression, which is
+transformed into the single argument
+.codn "(+ c d)" .
+No such transformation takes place for
+.code "(a list b c d)"
+because
+.code "(b c d)"
+isn't recognized infix; so these elements remain
+as individual arguments, such that the expression transforms into
+.codn "(list a b c d)" .
Only compound expressions are recognized as infix. A sequence
of atoms like