Sujet : Re: infix via code walker hook.
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.lispDate : 04. Apr 2025, 04:14:58
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250403192220.35@kylheku.com>
References : 1 2
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-04-02, Kaz Kylheku <
643-408-1753@kylheku.com> wrote:
On 2025-03-31, Kaz Kylheku <643-408-1753@kylheku.com> wrote:
(defmacro ifx (:env env . body)
(let ((*expand-hook* (fun infix-expand-hook)))
(expand ^(progn ,*body) env)))
>
Doh! I just though of expander-let which can do this nicely.
I'm serious about getting a form of infix as a supported
feature, and it's coming along.
The ground rules are: no read syntax. Everything is done using
existing syntax.
1> (ifx (let ((i 0))
(while (i ++ < 9)
(put-line (pic "## ## #.#####" i (i * i) (sqrt sin(i) ** 2 + sin(2 * i) ** 2))))))
1 1 1.23891
2 4 1.18304
3 9 0.31303
4 16 1.24562
5 25 1.10249
6 36 0.60497
7 49 1.18867
8 64 1.03040
9 81 0.85663
I have a Shunting Yard type infix parser which is extended with handling prefix
and postifix operators, as well as error checking. I converted the algorithm
to a pattern-based term rewriting system with two stacks. There are a few pure
term rewriting rules which do some nice things.
Here is one. I took numerous monadic math functions like sin, cos, log, and
turned them into very low precedence unary operators. What this means
is that sin is applied to the entire formula here:
1> (parse-infix '(sin a + b + c + d))
(sin (+ (+ (+ a b) c)
d))
But, if we put parentheses on the operand of sin, then it's no longer
the unary sin, but a function call with that argument:
2> (parse-infix '(sin (a) + b + c + d))
(+ (+ (+ (sin a) b)
c)
d)
3> (parse-infix '(sin (a + b) + c + d))
(+ (+ (sin a + b)
c)
d)
The parser has a hack like "if we are processing a unary operator
which is tagged as a function-like operator, and it is immediately
followed by a compound expression, then insert the operator as
the head operator into the compound expression".
Another term rewriting rule handles C-like [ ] array reference
agglutination:
4> (parse-infix '(a + b[i][j][k]))
(+ a [[[b i] j] k])
It's like magic; just use (ifx ...) around any expression or
even an entire top-level form like a defun, and you can freely
mix infix and regular Lisp in all evaluation contexts.
4> (ifx (list* 1 2 (mapcar (ret (@1 + @1)) '(10 20 30))))
(1 2 20 40 60)
5> (ifx (list* 1 2 (mapcar (lambda (x) (+ x x)) '(10 20 30))))
(1 2 20 40 60)
It's turning out ot be a pretty nice system, combining autodetection within an
explicit (ifx ...) contour.
I think it is already better than SRFI-105 curly braces and some other systems.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca