You have to make a choice:
- either you live in the lisp paradize,
- or you live in the other languages hell.
Living in the lisp paradize means that you just work with lisp data,
without caring about reading and lexical analysis, relying on the lisp
reader to do that for you.
Living in the other languages hell means that you will have to write
your own scanner and parser for the language you want to process. It
also means that it will be more difficult to mix lisp and this other
language in the same expression.
If you want to live in the lisp paradize, then forget about reading,
just use lisp sexps:
(defmacro def-rpn-fun (name parameters &body body)
`(progn
(setf (get ',name 'arity) ,(length parameters))
,(if (not (eq (find-package "COMMON-LISP")
(symbol-package name)))
`(defun ,name ,parameters ,@body)
`',name)))
(def-rpn-fun d (x) (values x x))
(def-rpn-fun v (x) (values (sqrt x)))
(def-rpn-fun + (x y) (values (+ x y)))
(def-rpn-fun - (x y) (values (- x y)))
(def-rpn-fun * (x y) (values (* x y)))
(def-rpn-fun / (x y) (values (/ x y)))
(def-rpn-fun tr (x y) (truncate x y))
(defun rpn (expr &optional stack)
(cond
((null expr) stack)
((numberp (first expr))
(rpn (rest expr) (cons (first expr) stack)))
((and (symbolp (first expr))
(fboundp (first expr))
(get (first expr) 'arity))
(rpn (rest expr)
(nreconc (multiple-value-list
(apply (first expr)
(loop :repeat (get (first expr) 'arity)
:collect (pop stack))))
stack)))
(t (error "invalid rpn ~S" expr))))
(assert (equal (rpn '(2 3 4 * +)) '(14)))
(assert (equal (rpn '(2 v 3 v * d *)) '(5.999999)))
(assert (equal (rpn '(210 v)) '(14.491377)))
(assert (equal (rpn '(2 4 -)) '(2)))
(assert (equal (rpn '(2 6 /)) '(3)))
(assert (equal (rpn '(3 10 tr)) '(1 3)))
(assert (equal (+ (first (rpn '(2 3 4 * *))) 100) 124))
(assert (equal (rpn (list 2 (/ 6 2) (* 2 2) '* '*)) '(24)))
If you want to scan and parse (this is quite funny actually), then study
the Dragon Book and write your scanner or parser (you may use a scanner
generator and a parser generator).
Anything else is a kludge.