Post Reply 
Conversion: Algebraic - Polish - Reverse Polish - LISP ?
11-03-2024, 05:37 PM
Post: #15
RE: Conversion: Algebraic - Polish - Reverse Polish - LISP ?
(11-03-2024 09:18 AM)Martin Hepperle Wrote:  And the example given by Albert Chan demonstrates nicely how LISP-like languages can be used to transform data into code and vice versa. But it seems to be a challenge to translate this to simpler LISPs like muLISP.

Scheme to Lisp is almost 1-to-1, with minor changes (define → defun, null? → null, ...)
Below '$', translated to muLisp, tested on Microsoft DOS MuLISP-86 5.10

Code:
(defun ^(x y) (expt x y)) ; need common.lsp expt
(defun process(e)       (scan (cdr  e) ($ (car e)) nil))
(defun rest(e)          (scan (cddr e) ($ (cadr e)) nil))
(defun do-term(a term)  (cons (car term) (cons a (cddr term))))
(defun build(a term)    (reduce do-term term a))

(defun scan(e a term)
    (cond
        ((null e)
            (build a term))
        ((member (car e) '(+ -))
            (if (null (cdr e))
                (build (list (car e) a) term)       ; unary +/- in front
                (if (member (cadr e) '(+ - * / ^))  ; unary +/- after op
                    (scan (cdr e) (list (car e) a) term)
                    (list (car e) (rest e) (build a term)))))
        ((member (car e) '(* /))
            (scan (cddr e) ($ (cadr e)) (cons (list (car e) #f a) term)))
        ((eq (car e) '^)
            (scan (cddr e) (list (car e) ($ (cadr e)) a) term))
        (else  ; implied multiply
            (scan (cdr  e) ($ (car e)) (cons (list '* #f a) term)))))

(defun $(e) ; infix -> prefix
    (cond
        ((atom e)                e)     ; nothing to do
        ((eq (car e) '@)    (cdr e))    ; (@ ...) --> (...)
        (else (process (reverse e)))))  ; process in reverse

D:\MULISP> mulisp common

; I have not figured out how to load lisp code, so I just cut/paste to muLisp REPL

$ ($ '(x (1 + x (1 - x)) (@ sin x)))
(* (* X (+ 1 (* X (- 1 X)))) (SIN X))

(11-01-2024 06:45 PM)Albert Chan Wrote:  scheme> (def v ($ '(5 *(((((1 + .2 *(350 / 661.5)^ 2)^ 3.5 - 1)* (1 - 6.875E-6 * 25500)^ - 5.2656)+ 1)^ .286 - 1))))
scheme> (sqrt (eval v))
0.8357245351752515

; muLisp does not understand number starting with decimal point, nor exponential notation

$ (setq v ($
'(5 *(((((1 + 0.2 *(350 / 661.5)^ 2)^ 3.5 - 1) *
(1 - 0.000006875 * 25500)^ - 5.2656)+ 1)^ 0.286 - 1))))

(* 5 (- (^ (+ (* (- (^ (+ 1 (* 0.2 (^ (/ 350 661.5) 2))) 3.5) 1) (^ (- 1 (*
0.0000068 25500)) (- 5.2656))) 1) 0.286) 1))

$ (sqrt (eval v))

0.8357245
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Conversion: Algebraic - Polish - Reverse Polish - LISP ? - Albert Chan - 11-03-2024 05:37 PM



User(s) browsing this thread: 9 Guest(s)