aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfgang Jenkner2015-01-15 20:02:17 +0100
committerWolfgang Jenkner2015-01-15 23:54:00 +0100
commit2290000ed69b1157739c280f090e5b60112e83fe (patch)
treef99e98a90548c979fa53347344d307bf25f225c1
parentb577fe28c73cacfd1e81dca5ebf8cc7b0830d957 (diff)
downloademacs-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/ChangeLog6
-rw-r--r--lisp/calc/calc-units.el16
-rw-r--r--test/ChangeLog7
-rw-r--r--test/automated/calc-tests.el52
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 @@
12015-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
12015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> 72015-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 @@
12015-01-15 Wolfgang Jenkner <wjenkner@inode.at> 12015-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
82015-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
52015-01-15 Stefan Monnier <monnier@iro.umontreal.ca> 122015-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.
40For example: (calc-tests-equal 10 '(float 1 1)) => t.
41A 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.
55The result is a calc (i.e., lisp) expression, not its string representation.
56Also pop the entire stack afterwards.
57An 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