From b296d0a20eabd9ea19bd66d9a822452fce8038e9 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 21 Apr 2025 09:46:54 -0700 Subject: 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. --- stdlib/infix.tl | 5 ++++- txr.1 | 34 ++++++++++++++++++++++++++++------ 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 -- cgit v1.2.3