diff options
| author | Wolfgang Jenkner | 2015-01-15 20:02:17 +0100 |
|---|---|---|
| committer | Wolfgang Jenkner | 2015-01-15 23:54:00 +0100 |
| commit | 2290000ed69b1157739c280f090e5b60112e83fe (patch) | |
| tree | f99e98a90548c979fa53347344d307bf25f225c1 | |
| parent | b577fe28c73cacfd1e81dca5ebf8cc7b0830d957 (diff) | |
| download | emacs-2290000ed69b1157739c280f090e5b60112e83fe.tar.gz emacs-2290000ed69b1157739c280f090e5b60112e83fe.zip | |
Handle the `neg' operator in some calc-units functions.
* lisp/calc/calc-units.el (math-units-in-expr-p)
(math-single-units-in-expr-p, math-find-compatible-unit-rec)
(math-extract-units): Handle the `neg' operator. (Bug#19582)
* test/automated/calc-tests.el (calc-tests-equal, calc-tests-simple):
New functions.
(test-calc-remove-units, test-calc-extract-units)
(test-calc-convert-units): New tests.
| -rw-r--r-- | lisp/ChangeLog | 6 | ||||
| -rw-r--r-- | lisp/calc/calc-units.el | 16 | ||||
| -rw-r--r-- | test/ChangeLog | 7 | ||||
| -rw-r--r-- | test/automated/calc-tests.el | 52 |
4 files changed, 77 insertions, 4 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index b7a38af9609..150f32f351a 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2015-01-15 Wolfgang Jenkner <wjenkner@inode.at> | ||
| 2 | |||
| 3 | * calc/calc-units.el (math-units-in-expr-p) | ||
| 4 | (math-single-units-in-expr-p, math-find-compatible-unit-rec) | ||
| 5 | (math-extract-units): Handle the `neg' operator. (Bug#19582) | ||
| 6 | |||
| 1 | 2015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> | 7 | 2015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 8 | ||
| 3 | * emacs-lisp/eieio-core.el: Provide support for cl-generic. | 9 | * emacs-lisp/eieio-core.el: Provide support for cl-generic. |
diff --git a/lisp/calc/calc-units.el b/lisp/calc/calc-units.el index 26a644a29ba..05950864a52 100644 --- a/lisp/calc/calc-units.el +++ b/lisp/calc/calc-units.el | |||
| @@ -904,10 +904,12 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 904 | (and (consp expr) | 904 | (and (consp expr) |
| 905 | (if (eq (car expr) 'var) | 905 | (if (eq (car expr) 'var) |
| 906 | (math-check-unit-name expr) | 906 | (math-check-unit-name expr) |
| 907 | (and (or sub-exprs | 907 | (if (eq (car expr) 'neg) |
| 908 | (memq (car expr) '(* / ^))) | 908 | (math-units-in-expr-p (nth 1 expr) sub-exprs) |
| 909 | (or (math-units-in-expr-p (nth 1 expr) sub-exprs) | 909 | (and (or sub-exprs |
| 910 | (math-units-in-expr-p (nth 2 expr) sub-exprs)))))) | 910 | (memq (car expr) '(* / ^))) |
| 911 | (or (math-units-in-expr-p (nth 1 expr) sub-exprs) | ||
| 912 | (math-units-in-expr-p (nth 2 expr) sub-exprs))))))) | ||
| 911 | 913 | ||
| 912 | (defun math-only-units-in-expr-p (expr) | 914 | (defun math-only-units-in-expr-p (expr) |
| 913 | (and (consp expr) | 915 | (and (consp expr) |
| @@ -924,6 +926,8 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 924 | (cond ((math-scalarp expr) nil) | 926 | (cond ((math-scalarp expr) nil) |
| 925 | ((eq (car expr) 'var) | 927 | ((eq (car expr) 'var) |
| 926 | (math-check-unit-name expr)) | 928 | (math-check-unit-name expr)) |
| 929 | ((eq (car expr) 'neg) | ||
| 930 | (math-single-units-in-expr-p (nth 1 expr))) | ||
| 927 | ((eq (car expr) '*) | 931 | ((eq (car expr) '*) |
| 928 | (let ((u1 (math-single-units-in-expr-p (nth 1 expr))) | 932 | (let ((u1 (math-single-units-in-expr-p (nth 1 expr))) |
| 929 | (u2 (math-single-units-in-expr-p (nth 2 expr)))) | 933 | (u2 (math-single-units-in-expr-p (nth 2 expr)))) |
| @@ -1079,6 +1083,8 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 1079 | ((eq (car-safe expr) '/) | 1083 | ((eq (car-safe expr) '/) |
| 1080 | (or (math-find-compatible-unit-rec (nth 1 expr) pow) | 1084 | (or (math-find-compatible-unit-rec (nth 1 expr) pow) |
| 1081 | (math-find-compatible-unit-rec (nth 2 expr) (- pow)))) | 1085 | (math-find-compatible-unit-rec (nth 2 expr) (- pow)))) |
| 1086 | ((eq (car-safe expr) 'neg) | ||
| 1087 | (math-find-compatible-unit-rec (nth 1 expr) pow)) | ||
| 1082 | ((and (eq (car-safe expr) '^) | 1088 | ((and (eq (car-safe expr) '^) |
| 1083 | (integerp (nth 2 expr))) | 1089 | (integerp (nth 2 expr))) |
| 1084 | (math-find-compatible-unit-rec (nth 1 expr) (* pow (nth 2 expr)))) | 1090 | (math-find-compatible-unit-rec (nth 1 expr) (* pow (nth 2 expr)))) |
| @@ -1497,6 +1503,8 @@ If COMP or STD is non-nil, put that in the units table instead." | |||
| 1497 | ((memq (car-safe expr) '(* /)) | 1503 | ((memq (car-safe expr) '(* /)) |
| 1498 | (cons (car expr) | 1504 | (cons (car expr) |
| 1499 | (mapcar 'math-extract-units (cdr expr)))) | 1505 | (mapcar 'math-extract-units (cdr expr)))) |
| 1506 | ((eq (car-safe expr) 'neg) | ||
| 1507 | (math-extract-units (nth 1 expr))) | ||
| 1500 | ((eq (car-safe expr) '^) | 1508 | ((eq (car-safe expr) '^) |
| 1501 | (list '^ (math-extract-units (nth 1 expr)) (nth 2 expr))) | 1509 | (list '^ (math-extract-units (nth 1 expr)) (nth 2 expr))) |
| 1502 | ((math-check-unit-name expr) expr) | 1510 | ((math-check-unit-name expr) expr) |
diff --git a/test/ChangeLog b/test/ChangeLog index 95d3e544aab..b3a0494267e 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2015-01-15 Wolfgang Jenkner <wjenkner@inode.at> | 1 | 2015-01-15 Wolfgang Jenkner <wjenkner@inode.at> |
| 2 | 2 | ||
| 3 | * automated/calc-tests.el (calc-tests-equal, calc-tests-simple): | ||
| 4 | New functions. | ||
| 5 | (test-calc-remove-units, test-calc-extract-units) | ||
| 6 | (test-calc-convert-units): New tests. | ||
| 7 | |||
| 8 | 2015-01-15 Wolfgang Jenkner <wjenkner@inode.at> | ||
| 9 | |||
| 3 | * automated/Makefile.in (WRITE_LOG): Use POSIX redirection. | 10 | * automated/Makefile.in (WRITE_LOG): Use POSIX redirection. |
| 4 | 11 | ||
| 5 | 2015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> | 12 | 2015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> |
diff --git a/test/automated/calc-tests.el b/test/automated/calc-tests.el index 331e01e4640..d5252ea62a9 100644 --- a/test/automated/calc-tests.el +++ b/test/automated/calc-tests.el | |||
| @@ -27,6 +27,40 @@ | |||
| 27 | (require 'cl-lib) | 27 | (require 'cl-lib) |
| 28 | (require 'ert) | 28 | (require 'ert) |
| 29 | (require 'calc) | 29 | (require 'calc) |
| 30 | (require 'calc-ext) | ||
| 31 | (require 'calc-units) | ||
| 32 | |||
| 33 | ;; XXX The order in which calc libraries (in particular calc-units) | ||
| 34 | ;; are loaded influences whether a calc integer in an expression | ||
| 35 | ;; involving units is represented as a lisp integer or a calc float, | ||
| 36 | ;; see bug#19582. Until this will be fixed the following function can | ||
| 37 | ;; be used to compare such calc expressions. | ||
| 38 | (defun calc-tests-equal (a b) | ||
| 39 | "Like `equal' but allow for different representations of numbers. | ||
| 40 | For example: (calc-tests-equal 10 '(float 1 1)) => t. | ||
| 41 | A and B should be calc expressions." | ||
| 42 | (cond ((math-numberp a) | ||
| 43 | (and (math-numberp b) | ||
| 44 | (math-equal a b))) | ||
| 45 | ((atom a) | ||
| 46 | (equal a b)) | ||
| 47 | ((consp b) | ||
| 48 | ;; Can't be dotted or circular. | ||
| 49 | (and (= (length a) (length b)) | ||
| 50 | (equal (car a) (car b)) | ||
| 51 | (cl-every #'calc-tests-equal (cdr a) (cdr b)))))) | ||
| 52 | |||
| 53 | (defun calc-tests-simple (fun string &rest args) | ||
| 54 | "Push STRING on the calc stack, then call FUN and return the new top. | ||
| 55 | The result is a calc (i.e., lisp) expression, not its string representation. | ||
| 56 | Also pop the entire stack afterwards. | ||
| 57 | An existing calc stack is reused, otherwise a new one is created." | ||
| 58 | (calc-eval string 'push) | ||
| 59 | (prog1 | ||
| 60 | (ignore-errors | ||
| 61 | (apply fun args) | ||
| 62 | (calc-top-n 1)) | ||
| 63 | (calc-pop 0))) | ||
| 30 | 64 | ||
| 31 | (ert-deftest test-math-bignum () | 65 | (ert-deftest test-math-bignum () |
| 32 | ;; bug#17556 | 66 | ;; bug#17556 |
| @@ -34,6 +68,24 @@ | |||
| 34 | (should (math-negp n)) | 68 | (should (math-negp n)) |
| 35 | (should (cl-notany #'cl-minusp (cdr n))))) | 69 | (should (cl-notany #'cl-minusp (cdr n))))) |
| 36 | 70 | ||
| 71 | (ert-deftest test-calc-remove-units () | ||
| 72 | (should (calc-tests-equal (calc-tests-simple #'calc-remove-units "-1 m") -1))) | ||
| 73 | |||
| 74 | (ert-deftest test-calc-extract-units () | ||
| 75 | (should (calc-tests-equal (calc-tests-simple #'calc-extract-units "-1 m") | ||
| 76 | '(var m var-m))) | ||
| 77 | (should (calc-tests-equal (calc-tests-simple #'calc-extract-units "-1 m*cm") | ||
| 78 | '(* (float 1 -2) (^ (var m var-m) 2))))) | ||
| 79 | |||
| 80 | (ert-deftest test-calc-convert-units () | ||
| 81 | ;; Used to ask for `(The expression is unitless when simplified) Old Units: '. | ||
| 82 | (should (calc-tests-equal (calc-tests-simple #'calc-convert-units "-1 m" nil "cm") | ||
| 83 | '(* -100 (var cm var-cm)))) | ||
| 84 | ;; Gave wrong result. | ||
| 85 | (should (calc-tests-equal (calc-tests-simple #'calc-convert-units "-1 m" | ||
| 86 | (math-read-expr "1m") "cm") | ||
| 87 | '(* -100 (var cm var-cm))))) | ||
| 88 | |||
| 37 | (provide 'calc-tests) | 89 | (provide 'calc-tests) |
| 38 | ;;; calc-tests.el ends here | 90 | ;;; calc-tests.el ends here |
| 39 | 91 | ||