-;;; calculator.el --- a [not so] simple calculator for Emacs
+;;; calculator.el --- a [not so] simple calculator for Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1998, 2000-2013 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 2000-2014 Free Software Foundation, Inc.
;; Author: Eli Barzilay <eli@barzilay.org>
;; Keywords: tools, convenience
be the name of a one-argument function, a string is used with a single
argument and an expression will be evaluated with the variable `num'
bound to whatever should be displayed. If it is a function symbol, it
-should be able to handle special symbol arguments, currently 'left and
-'right which will be sent by special keys to modify display parameters
+should be able to handle special symbol arguments, currently `left' and
+`right' which will be sent by special keys to modify display parameters
associated with the displayer function (for example to change the number
of digits displayed).
An exception to the above is the case of the list (std C) where C is a
character, in this case the `calculator-standard-displayer' function
will be used with this character for a format string."
+ :type '(choice (function) (string) (list (const std) character) (sexp))
:group 'calculator)
(defcustom calculator-displayers
;;;=====================================================================
;;; Code:
+(eval-when-compile (require 'cl-lib))
+
;;;---------------------------------------------------------------------
;;; Variables
(format calculator-displayer num))
((symbolp calculator-displayer)
(funcall calculator-displayer num))
- ((and (consp calculator-displayer)
- (eq 'std (car calculator-displayer)))
+ ((eq 'std (car-safe calculator-displayer))
(calculator-standard-displayer num (cadr calculator-displayer)))
((listp calculator-displayer)
- (eval calculator-displayer))
+ (eval calculator-displayer `((num. ,num))))
(t (prin1-to-string num t))))
;; operators are printed here
(t (prin1-to-string (nth 1 num) t))))
;; smaller than calculator-epsilon (1e-15). I don't think this is
;; necessary now.
(if (symbolp f)
- (cond ((and X Y) (funcall f X Y))
- (X (funcall f X))
- (t (funcall f)))
+ (cond ((and X Y) (funcall f X Y))
+ (X (funcall f X))
+ (t (funcall f)))
;; f is an expression
- (let* ((__f__ f) ; so we can get this value below...
- (TX (calculator-truncate X))
+ (let* ((TX (calculator-truncate X))
(TY (and Y (calculator-truncate Y)))
(DX (if calculator-deg (/ (* X pi) 180) X))
- (L calculator-saved-list)
- (Fbound (fboundp 'F))
- (Fsave (and Fbound (symbol-function 'F)))
- (Dbound (fboundp 'D))
- (Dsave (and Dbound (symbol-function 'D))))
- ;; a shortened version of flet
- (fset 'F (function
- (lambda (&optional x y)
- (calculator-funcall __f__ x y))))
- (fset 'D (function
- (lambda (x)
- (if calculator-deg (/ (* x 180) float-pi) x))))
- (unwind-protect (eval f)
- (if Fbound (fset 'F Fsave) (fmakunbound 'F))
- (if Dbound (fset 'D Dsave) (fmakunbound 'D)))))
+ (L calculator-saved-list))
+ (cl-letf (((symbol-function 'F)
+ (lambda (&optional x y) (calculator-funcall f x y)))
+ ((symbol-function 'D)
+ (lambda (x) (if calculator-deg (/ (* x 180) float-pi) x))))
+ (eval f `((X . ,X)
+ (Y . ,Y)
+ (TX . ,TX)
+ (TY . ,TY)
+ (DX . ,DX)
+ (L . ,L))))))
(error 0)))
;;;---------------------------------------------------------------------
(setq s (match-string 1 s)))
(kill-new s)))))
+;; FIXME this should use register-read-with-preview, but it
+;; uses calculator-registers rather than register-alist.
(defun calculator-set-register (reg)
"Set a register value for REG."
(interactive "cRegister to store into: ")
(or (match-string 3 str) ""))))
(ignore-errors (calculator-string-to-number str)))))
+;; FIXME this should use register-read-with-preview, but it
+;; uses calculator-registers rather than register-alist.
(defun calculator-get-register (reg)
"Get a value from a register REG."
(interactive "cRegister to get value from: ")