(defvar rpn-mode-map nil) (if rpn-mode-map () (setq rpn-mode-map (make-sparse-keymap)) (define-key rpn-mode-map "=" 'rpn-mode-eval-at-point)) (defun rpn-mode-to-lisp (tokens) (cond ((null tokens) (cons () ())) ((numberp (car tokens)) (cons (float (car tokens)) (cdr tokens))) (t (let* ((sndresult (rpn-mode-to-lisp (cdr tokens))) (fstresult (rpn-mode-to-lisp (cdr sndresult))) (snd (car sndresult)) (fst (car fstresult))) (if (or (null fst) (null snd)) (error "Stack underflow") (cons (list (car tokens) fst snd) (cdr fstresult))))))) (defun rpn-mode-eval-region (rbegin rend) (interactive "r") (message (prin1-to-string (eval (car (rpn-mode-to-lisp (mapcar (lambda (s) (car (read-from-string s))) (reverse (split-string (buffer-substring rbegin rend)))))))))) (defun rpn-mode-eval-buffer () (interactive) (rpn-mode-eval-region (point-min) (point-max))) (defun rpn-mode-eval-at-point () (interactive) (rpn-mode-eval-region (point-min) (point))) (defun rpn-mode () "Major mode implementing an RPN calculator" (interactive) (kill-all-local-variables) (use-local-map rpn-mode-map) (setq major-mode 'rpn-mode) (setq mode-name "RPN") (message "Press = to evaluate expression before cursor position") ) (provide 'rpn-mode)