home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume13 / gmcalc / part04 < prev    next >
Encoding:
Text File  |  1990-06-05  |  57.2 KB  |  1,839 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@csvax.caltech.edu (David Gillespie)
  3. Subject: v13i030: Emacs Calculator 1.01, part 04/19
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 30
  7. Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
  8. Archive-name: gmcalc/part04
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # this is part 4 of a multipart archive
  13. # do not concatenate these parts, unpack them in order with /bin/sh
  14. # file calc-ext.el continued
  15. #
  16. CurArch=4
  17. if test ! -r s2_seq_.tmp
  18. then echo "Please unpack part 1 first!"
  19.      exit 1; fi
  20. ( read Scheck
  21.   if test "$Scheck" != $CurArch
  22.   then echo "Please unpack part $Scheck next!"
  23.        exit 1;
  24.   else exit 0; fi
  25. ) < s2_seq_.tmp || exit 1
  26. echo "x - Continuing file calc-ext.el"
  27. sed 's/^X//' << 'SHAR_EOF' >> calc-ext.el
  28. X)
  29. X
  30. X(defun calc-ceiling (arg)
  31. X  "Truncate to an integer (toward plus infinity) the top element of the stack."
  32. X  (interactive "P")
  33. X  (calc-invert-func)
  34. X  (calc-floor arg)
  35. X)
  36. X
  37. X(defun calc-round (arg)
  38. X  "Round to the nearest integer the top element of the Calculator stack.
  39. XWith Inverse flag, truncate (toward zero) to an integer.
  40. XWith Hyperbolic flag, represent result in floating-point."
  41. X  (interactive "P")
  42. X  (calc-slow-wrapper
  43. X   (if (calc-is-inverse)
  44. X       (if (calc-is-hyperbolic)
  45. X       (calc-unary-op "trnc" 'calcFunc-ftrunc arg)
  46. X     (calc-unary-op "trnc" 'calcFunc-trunc arg))
  47. X     (if (calc-is-hyperbolic)
  48. X     (calc-unary-op "rond" 'calcFunc-fround arg)
  49. X       (calc-unary-op "rond" 'calcFunc-round arg))))
  50. X)
  51. X
  52. X(defun calc-trunc (arg)
  53. X  "Truncate to an integer (toward zero) the top element of the Calculator stack."
  54. X  (interactive "P")
  55. X  (calc-invert-func)
  56. X  (calc-round arg)
  57. X)
  58. X
  59. X(defun calc-abssqr (arg)
  60. X  "Compute the absolute value squared of the top element of the stack."
  61. X  (interactive "P")
  62. X  (calc-slow-wrapper
  63. X   (calc-unary-op "absq" 'calcFunc-abssqr arg))
  64. X)
  65. X
  66. X(defun calc-argument (arg)
  67. X  "Compute the complex argument of the top element of the Calculator stack."
  68. X  (interactive "P")
  69. X  (calc-slow-wrapper
  70. X   (calc-unary-op "arg" 'calcFunc-arg arg))
  71. X)
  72. X
  73. X(defun calc-re (arg)
  74. X  "Replace the top element of the Calculator stack with its real part."
  75. X  (interactive "P")
  76. X  (calc-slow-wrapper
  77. X   (calc-unary-op "re" 'calcFunc-re arg))
  78. X)
  79. X
  80. X(defun calc-im (arg)
  81. X  "Replace the top element of the Calculator stack with its imaginary part."
  82. X  (interactive "P")
  83. X  (calc-slow-wrapper
  84. X   (calc-unary-op "im" 'calcFunc-im arg))
  85. X)
  86. X
  87. X(defun calc-hypot (arg)
  88. X  "Take the square root of sum of squares of the top two elements of the stack."
  89. X  (interactive "P")
  90. X  (calc-slow-wrapper
  91. X   (calc-binary-op "hypt" 'calcFunc-hypot arg))
  92. X)
  93. X
  94. X(defun calc-ln (arg)
  95. X  "Take the natural logarithm of the top element of the Calculator stack.
  96. XWith Inverse flag or negative prefix arg, computes e^x.
  97. XWith Hyperbolic flag or even prefix arg, computes log_10 or 10^x."
  98. X  (interactive "P")
  99. X  (calc-invert-func)
  100. X  (calc-exp arg)
  101. X)
  102. X
  103. X(defun calc-log10 (arg)
  104. X  "Take the logarithm (base 10) of the top element of the Calculator stack.
  105. XWith Inverse flag or negative prefix arg, computes 10^x."
  106. X  (interactive "P")
  107. X  (calc-hyperbolic-func)
  108. X  (calc-ln arg)
  109. X)
  110. X
  111. X(defun calc-log (arg)
  112. X  "Take the logarithm base B of X.  B is top-of-stack, X is second-to-top.
  113. XWith Inverse flag, computes B^X.  (Note that \"^\" would compute X^B.)"
  114. X  (interactive "P")
  115. X  (calc-slow-wrapper
  116. X   (if (calc-is-inverse)
  117. X       (calc-binary-op "Ilog" 'calcFunc-ilog arg)
  118. X     (calc-binary-op "log" 'calcFunc-log arg)))
  119. X)
  120. X
  121. X(defun calc-lnp1 (arg)
  122. X  "Take the logarithm (ln(x+1)) of one plus the top element of the stack."
  123. X  (interactive "P")
  124. X  (calc-invert-func)
  125. X  (calc-expm1 arg)
  126. X)
  127. X
  128. X(defun calc-exp (arg)
  129. X  "Take the exponential (e^x) of the top element of the Calculator stack.
  130. XWith Inverse flag or negative prefix arg, takes the natural logarithm.
  131. XWith Hyperbolic flag or even prefix arg, computes 10^x or log_10."
  132. X  (interactive "P")
  133. X  (calc-slow-wrapper
  134. X   (if (calc-is-hyperbolic)
  135. X       (if (calc-is-inverse)
  136. X       (calc-unary-op "lg10" 'calcFunc-log10 arg)
  137. X     (calc-unary-op "10^" 'calcFunc-pow10 arg))
  138. X     (if (calc-is-inverse)
  139. X     (calc-unary-op "ln" 'calcFunc-ln arg)
  140. X       (calc-unary-op "exp" 'calcFunc-exp arg))))
  141. X)
  142. X
  143. X(defun calc-expm1 (arg)
  144. X  "Take the exponential minus one (e^x - 1) of the top element of the stack."
  145. X  (interactive "P")
  146. X  (calc-slow-wrapper
  147. X   (if (calc-is-inverse)
  148. X       (calc-unary-op "ln+1" 'calcFunc-lnp1 arg)
  149. X     (calc-unary-op "ex-1" 'calcFunc-expm1 arg)))
  150. X)
  151. X
  152. X(defun calc-pi ()
  153. X  "Push Pi (at the current precision) on the Calculator stack.
  154. XWith Hyperbolic flag, pushes `e' (the base of natural logarithms)."
  155. X  (interactive)
  156. X  (calc-slow-wrapper
  157. X   (if (calc-is-hyperbolic)
  158. X       (if calc-symbolic-mode
  159. X       (calc-pop-push-record 0 "e" '(var e var-e))
  160. X     (calc-pop-push-record 0 "e" (math-e)))
  161. X     (if calc-symbolic-mode
  162. X     (calc-pop-push-record 0 "pi" '(var pi var-pi))
  163. X       (calc-pop-push-record 0 "pi" (math-pi)))))
  164. X)
  165. X
  166. X(defun calc-sin (arg)
  167. X  "Take the sine of the top element of the Calculator stack.
  168. XWith Inverse flag or negative prefix arg, takes the inverse sine.
  169. XWith Hyperbolic flag or even prefix arg, computes sinh or arcsinh."
  170. X  (interactive "P")
  171. X  (calc-slow-wrapper
  172. X   (if (calc-is-hyperbolic)
  173. X       (if (calc-is-inverse)
  174. X       (calc-unary-op "asnh" 'calcFunc-arcsinh arg)
  175. X     (calc-unary-op "sinh" 'calcFunc-sinh arg))
  176. X     (if (calc-is-inverse)
  177. X     (calc-unary-op "asin" 'calcFunc-arcsin arg)
  178. X       (calc-unary-op "sin" 'calcFunc-sin arg))))
  179. X)
  180. X
  181. X(defun calc-arcsin (arg)
  182. X  "Take the inverse sine of the top element of the Calculator stack."
  183. X  (interactive "P")
  184. X  (calc-invert-func)
  185. X  (calc-sin arg)
  186. X)
  187. X
  188. X(defun calc-sinh (arg)
  189. X  "Take the hyperbolic sine of the top element of the Calculator stack."
  190. X  (interactive "P")
  191. X  (calc-hyperbolic-func)
  192. X  (calc-sin arg)
  193. X)
  194. X
  195. X(defun calc-arcsinh (arg)
  196. X  "Take the inverse hyperbolic sine of the top element of the Calculator stack."
  197. X  (interactive "P")
  198. X  (calc-invert-func)
  199. X  (calc-hyperbolic-func)
  200. X  (calc-sin arg)
  201. X)
  202. X
  203. X(defun calc-cos (arg)
  204. X  "Take the cosine of the top element of the Calculator stack.
  205. XWith Inverse flag or negative prefix arg, takes the inverse cosine.
  206. XWith Hyperbolic flag or even prefix arg, computes cosh or arccosh."
  207. X  (interactive "P")
  208. X  (calc-slow-wrapper
  209. X   (if (calc-is-hyperbolic)
  210. X       (if (calc-is-inverse)
  211. X       (calc-unary-op "acsh" 'calcFunc-arccosh arg)
  212. X     (calc-unary-op "cosh" 'calcFunc-cosh arg))
  213. X     (if (calc-is-inverse)
  214. X     (calc-unary-op "acos" 'calcFunc-arccos arg)
  215. X       (calc-unary-op "cos" 'calcFunc-cos arg))))
  216. X)
  217. X
  218. X(defun calc-arccos (arg)
  219. X  "Take the inverse cosine of the top element of the Calculator stack."
  220. X  (interactive "P")
  221. X  (calc-invert-func)
  222. X  (calc-cos arg)
  223. X)
  224. X
  225. X(defun calc-cosh (arg)
  226. X  "Take the hyperbolic cosine of the top element of the Calculator stack."
  227. X  (interactive "P")
  228. X  (calc-hyperbolic-func)
  229. X  (calc-cos arg)
  230. X)
  231. X
  232. X(defun calc-arccosh (arg)
  233. X  "Take the inverse hyperbolic cosine of the top element of the Calculator stack."
  234. X  (interactive "P")
  235. X  (calc-invert-func)
  236. X  (calc-hyperbolic-func)
  237. X  (calc-cos arg)
  238. X)
  239. X
  240. X(defun calc-sincos ()
  241. X  "Compute the sine and cosine of the top element of the Calculator stack.
  242. XResult is a vector [cos(x), sin(x)].
  243. XInverse and Hyperbolic flags are not recognized."
  244. X  (interactive)
  245. X  (calc-slow-wrapper
  246. X   (if (calc-is-inverse)
  247. X       (calc-enter-result 1 "asnc" (list 'calcFunc-arcsincos (calc-top-n 1)))
  248. X     (calc-enter-result 1 "sncs" (list 'calcFunc-sincos (calc-top-n 1)))))
  249. X)
  250. X
  251. X(defun calc-tan (arg)
  252. X  "Take the tangent of the top element of the Calculator stack.
  253. XWith Inverse flag or negative prefix arg, takes the inverse tangent.
  254. XWith Hyperbolic flag or even prefix arg, computes tanh or arctanh."
  255. X  (interactive "P")
  256. X  (calc-slow-wrapper
  257. X   (if (calc-is-hyperbolic)
  258. X       (if (calc-is-inverse)
  259. X       (calc-unary-op "atnh" 'calcFunc-arctanh arg)
  260. X     (calc-unary-op "tanh" 'calcFunc-tanh arg))
  261. X     (if (calc-is-inverse)
  262. X     (calc-unary-op "atan" 'calcFunc-arctan arg)
  263. X       (calc-unary-op "tan" 'calcFunc-tan arg))))
  264. X)
  265. X
  266. X(defun calc-arctan (arg)
  267. X  "Take the inverse tangent of the top element of the Calculator stack."
  268. X  (interactive "P")
  269. X  (calc-invert-func)
  270. X  (calc-tan arg)
  271. X)
  272. X
  273. X(defun calc-tanh (arg)
  274. X  "Take the hyperbolic tangent of the top element of the Calculator stack."
  275. X  (interactive "P")
  276. X  (calc-hyperbolic-func)
  277. X  (calc-tan arg)
  278. X)
  279. X
  280. X(defun calc-arctanh (arg)
  281. X  "Take the inverse hyperbolic tangent of the top element of the stack."
  282. X  (interactive "P")
  283. X  (calc-invert-func)
  284. X  (calc-hyperbolic-func)
  285. X  (calc-tan arg)
  286. X)
  287. X
  288. X(defun calc-arctan2 ()
  289. X  "Compute the full-circle arc tangent of the ratio of two numbers."
  290. X  (interactive)
  291. X  (calc-slow-wrapper
  292. X   (calc-enter-result 2 "atn2" (cons 'calcFunc-arctan2 (calc-top-list-n 2))))
  293. X)
  294. X
  295. X(defun calc-conj (arg)
  296. X  "Compute the complex conjugate of the top element of the Calculator stack."
  297. X  (interactive "P")
  298. X  (calc-wrapper
  299. X   (calc-unary-op "conj" 'calcFunc-conj arg))
  300. X)
  301. X
  302. X(defun calc-imaginary ()
  303. X  "Multiply the top element of the Calculator stack by complex \"i\"."
  304. X  (interactive)
  305. X  (calc-slow-wrapper
  306. X   (calc-pop-push-record 1 "i*" (math-imaginary (calc-top-n 1))))
  307. X)
  308. X
  309. X
  310. X
  311. X;;; Memory commands.
  312. X
  313. X(defun calc-store (n &optional var oper)
  314. X  "Store the value at the top of the Calculator stack in variable VAR.
  315. XIf VAR is of the form +V, -V, *V, /V, ^V, or |V, top of stack is combined
  316. Xinto V with the appropriate operation.
  317. XWith any numeric prefix argument, unsets the specified variable."
  318. X  (interactive "P")
  319. X  (calc-wrapper
  320. X   (if n
  321. X       (progn
  322. X     (or var
  323. X         (setq var (let ((minibuffer-completion-table obarray)
  324. X                 (minibuffer-completion-predicate 'boundp)
  325. X                 (minibuffer-completion-confirm t)
  326. X                 (oper "r"))
  327. X             (read-from-minibuffer
  328. X              "Unstore: " "var-" calc-store-var-map nil))))
  329. X     (if (equal var "")
  330. X         ()
  331. X       (makunbound (intern var))))
  332. X     (while (or (null var) (equal var "")
  333. X        (string-match "\\`[-+*/^|].*" var))
  334. X       (if (and var (> (length var) 0))
  335. X       (setq oper (substring var 0 1)
  336. X         var (substring var 1))
  337. X     (setq var (let ((minibuffer-completion-table obarray)
  338. X             (minibuffer-completion-predicate 'boundp)
  339. X             (minibuffer-completion-confirm t))
  340. X             (read-from-minibuffer
  341. X              (if oper (format "Store %s: " oper) "Store: ")
  342. X              "var-" calc-store-var-map nil)))))
  343. X     (if (equal var "")
  344. X     ()
  345. X       (let* ((ivar (intern var))
  346. X          (ival (if (boundp ivar) (symbol-value ivar) nil)))
  347. X     (if (null oper)
  348. X         (set ivar (calc-top 1))
  349. X       (if (null ival)
  350. X           (error "No such variable"))
  351. X       (setq ival (calc-normalize ival))
  352. X       (cond ((equal oper "+")
  353. X          (set ivar (calc-normalize
  354. X                 (list '+ ival (calc-top-n 1)))))
  355. X         ((equal oper "-")
  356. X          (set ivar (calc-normalize
  357. X                 (list '- ival (calc-top-n 1)))))
  358. X         ((equal oper "*")
  359. X          (set ivar (calc-normalize
  360. X                 (list '* ival (calc-top-n 1)))))
  361. X         ((equal oper "/")
  362. X          (set ivar (calc-normalize
  363. X                 (list '/ ival (calc-top-n 1)))))
  364. X         ((equal oper "^")
  365. X          (set ivar (calc-normalize
  366. X                 (list '^ ival (calc-top-n 1)))))
  367. X         ((equal oper "|")
  368. X          (set ivar (calc-normalize
  369. X                 (list '| ival (calc-top-n 1)))))))
  370. X     (calc-record-undo (list 'store var ival))
  371. X     (calc-record (symbol-value ivar)
  372. X              (concat ">" (or oper "")
  373. X                  (if (string-match "\\`var-.+\\'" var)
  374. X                  (substring var 4) var)))))))
  375. X)
  376. X
  377. X(defun calc-unstore (&optional var oper)
  378. X  (interactive)
  379. X  (calc-store -1 var oper)
  380. X)
  381. X
  382. X(defvar calc-store-var-map nil "Keymap for use by the calc-store command.")
  383. X(if calc-store-var-map
  384. X    ()
  385. X  (setq calc-store-var-map (copy-keymap minibuffer-local-completion-map))
  386. X  (mapcar (function
  387. X       (lambda (x)
  388. X         (define-key calc-store-var-map (char-to-string x)
  389. X           'calcVar-digit)))
  390. X      "0123456789")
  391. X  (mapcar (function
  392. X       (lambda (x)
  393. X         (define-key calc-store-var-map (char-to-string x)
  394. X           'calcVar-oper)))
  395. X      "+-*/^|")
  396. X)
  397. X
  398. X(defun calcVar-digit ()
  399. X  (interactive)
  400. X  (if (calc-minibuffer-contains "var-\\'")
  401. X      (self-insert-and-exit)
  402. X    (self-insert-command 1))
  403. X)
  404. X
  405. X(defun calcVar-oper ()
  406. X  (interactive)
  407. X  (if (calc-minibuffer-contains "var-\\'")
  408. X      (if (null oper)
  409. X      (progn
  410. X        (erase-buffer)
  411. X        (self-insert-and-exit))
  412. X    (beep))
  413. X    (self-insert-command 1))
  414. X)
  415. X
  416. X(defun calc-recall (&optional var)
  417. X  "Recall the value of variable VAR into the Calculator stack."
  418. X  (interactive)
  419. X  (calc-wrapper
  420. X   (or var
  421. X       (setq var (let ((minibuffer-completion-table obarray)
  422. X               (minibuffer-completion-predicate 'boundp)
  423. X               (minibuffer-completion-confirm t)
  424. X               (oper "r"))
  425. X           (read-from-minibuffer
  426. X            "Recall: " "var-" calc-store-var-map nil))))
  427. X   (if (equal var "")
  428. X       ()
  429. X     (setq ivar (intern var))
  430. X     (if (not (and (boundp ivar) ivar))
  431. X     (error "No such variable"))
  432. X     (let ((ival (symbol-value ivar)))
  433. X       (setq ival (calc-normalize ival))
  434. X       (calc-record ival (concat "<"
  435. X                 (if (string-match "\\`var-.+\\'" var)
  436. X                     (substring var 4) var)))
  437. X       (calc-push ival))))
  438. X)
  439. X
  440. X(defun calc-let (&optional var)
  441. X  "Evaluate second-in-stack where variable VAR equals top of stack."
  442. X  (interactive)
  443. X  (calc-wrapper
  444. X   (or var
  445. X       (setq var (let ((minibuffer-completion-table obarray)
  446. X               (minibuffer-completion-predicate 'boundp)
  447. X               (minibuffer-completion-confirm t)
  448. X               (oper "r"))
  449. X           (read-from-minibuffer
  450. X            "Let variable: " "var-" calc-store-var-map nil))))
  451. X   (if (equal var "")
  452. X       ()
  453. X     (setq ivar (intern var))
  454. X     (calc-pop-push-record
  455. X      2 (concat "="
  456. X        (if (string-match "\\`var-.+\\'" var)
  457. X            (substring var 4) var))
  458. X      (let ((saved-val (and (boundp ivar) (symbol-value ivar))))
  459. X    (unwind-protect
  460. X        (progn
  461. X          (set ivar (calc-top-n 1))
  462. X          (math-evaluate-expr (calc-top-n 2)))
  463. X      (if saved-val
  464. X          (set ivar saved-val)
  465. X        (makunbound ivar)))))))
  466. X)
  467. X
  468. X
  469. X
  470. X
  471. X;;; Kill ring commands.
  472. X
  473. X(defun calc-kill (nn &optional no-delete)
  474. X  "Kill the Calculator stack element containing the cursor.
  475. XWith numeric prefix argument N, kill the N stack elements at+below cursor."
  476. X  (interactive "P")
  477. X  (calc-wrapper
  478. X   (calc-force-refresh)
  479. X   (calc-set-command-flag 'no-align)
  480. X   (let ((num (max (calc-locate-cursor-element (point)) 1))
  481. X     (n (prefix-numeric-value nn)))
  482. X     (if (< n 0)
  483. X     (progn
  484. X       (if (eobp)
  485. X           (setq num (1- num)))
  486. X       (setq num (- num n)
  487. X         n (- n))))
  488. X     (let ((stuff (calc-top-list n (- num n -1))))
  489. X       (calc-cursor-stack-index num)
  490. X       (let ((first (point)))
  491. X     (calc-cursor-stack-index (- num n))
  492. X     (if (null nn)
  493. X         (backward-char 1))   ; don't include newline for raw C-k
  494. X     (copy-region-as-kill first (point))
  495. X     (if (not no-delete)
  496. X         (calc-pop-stack n (- num n -1))))
  497. X       (setq calc-last-kill (cons (car kill-ring) stuff)))))
  498. X)
  499. X
  500. X(defun calc-force-refresh ()
  501. X  (if calc-executing-macro
  502. X      (let ((calc-executing-macro nil))
  503. X    (calc-refresh)))
  504. X)
  505. X
  506. X(defun calc-locate-cursor-element (pt)
  507. X  (save-excursion
  508. X    (goto-char (point-max))
  509. X    (calc-locate-cursor-scan (- calc-stack-top) calc-stack pt))
  510. X)
  511. X
  512. X(defun calc-locate-cursor-scan (n stack pt)
  513. X  (if (or (<= (point) pt)
  514. X      (null stack))
  515. X      n
  516. X    (forward-line (- (nth 1 (car stack))))
  517. X    (calc-locate-cursor-scan (1+ n) (cdr stack) pt))
  518. X)
  519. X
  520. X(defun calc-kill-region (top bot &optional no-delete)
  521. X  "Kill the Calculator stack elements between Point and Mark."
  522. X  (interactive "r")
  523. X  (calc-wrapper
  524. X   (calc-force-refresh)
  525. X   (calc-set-command-flag 'no-align)
  526. X   (let* ((top-num (calc-locate-cursor-element top))
  527. X      (bot-num (calc-locate-cursor-element (1- bot)))
  528. X      (num (- top-num bot-num -1)))
  529. X     (copy-region-as-kill top bot)
  530. X     (setq calc-last-kill (cons (car kill-ring) (calc-top-list num bot-num)))
  531. X     (if (not no-delete)
  532. X     (calc-pop-stack num bot-num))))
  533. X)
  534. X
  535. X(defun calc-copy-as-kill (n)
  536. X  "Copy the Calculator stack element containing the cursor into the Kill Ring.
  537. XThe stack element is not deleted.  With numeric prefix argument N, copy the
  538. XN stack elements at+below cursor."
  539. X  (interactive "P")
  540. X  (calc-kill n t)
  541. X)
  542. X
  543. X(defun calc-copy-region-as-kill (top bot)
  544. X  "Copy the Calculator stack elements between Point and Mark into the Kill Ring.
  545. XThe stack elements are not deleted."
  546. X  (interactive "r")
  547. X  (calc-kill-region top bot t)
  548. X)
  549. X
  550. X;;; This function uses calc-last-kill if possible to get an exact result,
  551. X;;; otherwise it just parses the yanked string.
  552. X(defun calc-yank ()
  553. X  "Enter the contents of the last Killed text into the Calculator stack.
  554. XThis text must be formatted as a number or list of numbers."
  555. X  (interactive)
  556. X  (calc-wrapper
  557. X   (calc-pop-push-record-list
  558. X    0 "yank"
  559. X    (if (eq (car-safe calc-last-kill) (car kill-ring-yank-pointer))
  560. X    (cdr calc-last-kill)
  561. X      (if (stringp (car kill-ring-yank-pointer))
  562. X      (let ((val (math-read-exprs
  563. X              (calc-clean-newlines (car kill-ring-yank-pointer)))))
  564. X        (if (eq (car-safe val) 'error)
  565. X        (error "Bad format in yanked data")
  566. X          val))))))
  567. X)
  568. X
  569. X(defun calc-clean-newlines (s)
  570. X  (cond
  571. X   
  572. X   ;; Omit leading/trailing whitespace
  573. X   ((or (string-match "\\`[ \n\r]+\\([^\001]*\\)\\'" s)
  574. X    (string-match "\\`\\([^\001]*\\)[ \n\r]+\\'" s))
  575. X    (calc-clean-newlines (math-match-substring s 1)))
  576. X
  577. X   ;; Convert newlines to commas
  578. X   ((string-match "\\`\\(.*\\)[\n\r]+\\([^\001]*\\)\\'" s)
  579. X    (calc-clean-newlines (concat (math-match-substring s 1) ","
  580. X                 (math-match-substring s 2))))
  581. X   
  582. X   (t s))
  583. X)
  584. X
  585. X(defun calc-grab-region (top bot)
  586. X  "Parse the region as a matrix of numbers and push it on the Calculator stack.
  587. XThis is intended to be used in a non-Calculator buffer!
  588. XIf the start and the end of the region are in column zero, the contained lines
  589. Xare parsed into rows of the matrix.  Otherwise, point and mark define a
  590. Xrectangle which is parsed into a matrix."
  591. X  (interactive "r")
  592. X  (and (memq major-mode '(calc-mode calc-trail-mode))
  593. X       (error "This command works only in a regular text buffer."))
  594. X  (let* ((col1 (save-excursion (goto-char top) (current-column)))
  595. X     (col2 (save-excursion (goto-char bot) (current-column)))
  596. X     (from-buffer (current-buffer))
  597. X     data mat vals lnum pt pos)
  598. X    (if (= col1 col2)
  599. X    (save-excursion
  600. X      (or (= col1 0)
  601. X          (error "Point and mark must be at beginning of line, or define a rectangle"))
  602. X      (goto-char top)
  603. X      (while (< (point) bot)
  604. X        (setq pt (point))
  605. X        (forward-line 1)
  606. X        (setq data (cons (buffer-substring pt (1- (point))) data)))
  607. X      (setq data (nreverse data)))
  608. X      (setq data (extract-rectangle top bot)))
  609. X    (calc)
  610. X    (setq mat (list 'vec)
  611. X      lnum 0)
  612. X    (while data
  613. X      (if (string-match "[[{][^][{}]*[]}]" (car data))
  614. X      (setq pos (match-beginning 0)
  615. X        vals (math-read-expr (math-match-substring (car data) 0)))
  616. X    (if (string-match "\\`\\([0-9]+:[ \t]\\)?\\(.*[^, \t]\\)[, \t]*\\'" (car data))
  617. X        (setq pos -1
  618. X          vals (math-read-expr (concat "["
  619. X                           (math-match-substring
  620. X                        (car data) 2)
  621. X                           "]")))
  622. X      (setq pos -1
  623. X        vals (math-read-expr (concat "[" (car data) "]")))))
  624. X      (if (eq (car-safe vals) 'error)
  625. X      (progn
  626. X        (calc-quit)
  627. X        (switch-to-buffer from-buffer)
  628. X        (goto-char top)
  629. X        (next-line lnum)
  630. X        (forward-char (+ (nth 1 vals) pos))
  631. X        (error (nth 2 vals))))
  632. X      (setq mat (cons vals mat)
  633. X        data (cdr data)
  634. X        lnum (1+ lnum)))
  635. X    (calc-wrapper
  636. X     (calc-enter-result 0 "grab" (nreverse mat))))
  637. X)
  638. X
  639. X(defun calc-copy-to-buffer (nn)
  640. X  "Copy the top of stack into the most recently used editing buffer.
  641. XWith a positive numeric prefix argument, copy the top N lines.
  642. XWith a negative argument, copy the Nth line.
  643. XWith an argument of zero, copy the entire stack.
  644. XWith plain \"C-u\" as an argument, replaces region in other buffer."
  645. X  (interactive "P")
  646. X  (let (oldbuf newbuf)
  647. X    (calc-wrapper
  648. X     (save-excursion
  649. X       (calc-force-refresh)
  650. X       (let ((n (prefix-numeric-value nn))
  651. X         top bot)
  652. X     (setq oldbuf (current-buffer)
  653. X           newbuf (or (calc-find-writable-buffer (buffer-list) 0)
  654. X              (calc-find-writable-buffer (buffer-list) 1)
  655. X              (error "No other buffer")))
  656. X     (cond ((and (or (null nn)
  657. X             (consp nn))
  658. X             (= (calc-substack-height 0)
  659. X            (1- (calc-substack-height 1))))
  660. X        (calc-cursor-stack-index 1)
  661. X        (if (looking-at
  662. X             (if calc-line-numbering "[0-9]+: *[^ \n]" " *[^ \n]"))
  663. X            (goto-char (1- (match-end 0))))
  664. X        (setq top (point))
  665. X        (calc-cursor-stack-index 0)
  666. X        (setq bot (1- (point))))
  667. X           ((> n 0)
  668. X        (calc-cursor-stack-index n)
  669. X        (setq top (point))
  670. X        (calc-cursor-stack-index (1- n))
  671. X        (setq bot (point)))
  672. X           ((< n 0)
  673. X        (calc-cursor-stack-index (- n))
  674. X        (setq top (point))
  675. X        (calc-cursor-stack-index (1- (- n)))
  676. X        (setq bot (point)))
  677. X           (t
  678. X        (goto-char (point-min))
  679. X        (forward-line 1)
  680. X        (setq top (point))
  681. X        (calc-cursor-stack-index 0)
  682. X        (setq bot (point))))
  683. X     (save-excursion
  684. X       (set-buffer newbuf)
  685. X       (if (consp nn)
  686. X           (kill-region (region-beginning) (region-end)))
  687. X       (push-mark (point) t)
  688. X       (insert-buffer-substring oldbuf top bot)
  689. X       (if (get-buffer-window (current-buffer))
  690. X           (set-window-point (get-buffer-window (current-buffer))
  691. X                 (point)))))))
  692. X    (if (consp nn)
  693. X    (progn
  694. X      (calc-quit)
  695. X      (switch-to-buffer newbuf))))
  696. X)
  697. X
  698. X;;; First, require that buffer is visible and does not begin with "*"
  699. X;;; Second, require only that it not begin with "*Calc"
  700. X(defun calc-find-writable-buffer (buf mode)
  701. X  (and buf
  702. X       (if (or (string-match "\\`\\( .*\\|\\*Calc.*\\)"
  703. X                 (buffer-name (car buf)))
  704. X           (and (= mode 0)
  705. X            (or (string-match "\\`\\*.*" (buffer-name (car buf)))
  706. X            (not (get-buffer-window (car buf))))))
  707. X       (calc-find-writable-buffer (cdr buf) mode)
  708. X     (car buf)))
  709. X)
  710. X
  711. X(defun calc-edit (n)
  712. X  "Edit the top entry on the stack using normal Emacs editing commands.
  713. XWith a positive numeric prefix, edit the top N elements of the stack.
  714. XWith a zero prefix, edit all stack elements.
  715. XType RET or LFD or C-c C-c to finish editing."
  716. X  (interactive "p")
  717. X  (calc-wrapper
  718. X   (if (= n 0)
  719. X       (setq n (calc-stack-size)))
  720. X   (if (< n 0)
  721. X       (error "Argument must be positive or zero"))
  722. X   (let ((list (mapcar (function (lambda (x) (math-format-flat-expr x 0)))
  723. X               (calc-top-list n))))
  724. X     (calc-edit-mode (list 'calc-finish-stack-edit n))
  725. X     (while list
  726. X       (insert (car list) "\n")
  727. X       (setq list (cdr list)))))
  728. X  (calc-show-edit-buffer)
  729. X)
  730. X
  731. X(defvar calc-edit-mode-map nil "Keymap for use by the calc-edit command.")
  732. X(if calc-edit-mode-map
  733. X    ()
  734. X  (setq calc-edit-mode-map (make-sparse-keymap))
  735. X  (define-key calc-edit-mode-map "\n" 'calc-edit-finish)
  736. X  (define-key calc-edit-mode-map "\r" 'calc-edit-finish)
  737. X  (define-key calc-edit-mode-map "\C-c\C-c" 'calc-edit-finish)
  738. X)
  739. X
  740. X(defun calc-edit-mode (&optional handler)
  741. X  "Calculator editing mode.  Press RET, LFD, or C-c C-c to finish.
  742. XTo cancel the edit, simply kill the *Calc Edit* buffer."
  743. X  (interactive)
  744. X  (or handler
  745. X      (error "This command can be used only indirectly through calc-edit."))
  746. X  (let ((oldbuf (current-buffer))
  747. X    (buf (get-buffer-create "*Calc Edit*")))
  748. X    (set-buffer buf)
  749. X    (kill-all-local-variables)
  750. X    (use-local-map calc-edit-mode-map)
  751. X    (setq buffer-read-only nil)
  752. X    (setq truncate-lines nil)
  753. X    (setq major-mode 'calc-edit-mode)
  754. X    (setq mode-name "Calc Edit")
  755. X    (run-hooks 'calc-edit-mode-hook)
  756. X    (make-local-variable 'calc-original-buffer)
  757. X    (setq calc-original-buffer oldbuf)
  758. X    (make-local-variable 'calc-edit-handler)
  759. X    (setq calc-edit-handler handler)
  760. X    (make-local-variable 'calc-restore-trail)
  761. X    (setq calc-restore-trail calc-display-trail)
  762. X    (erase-buffer)
  763. X    (insert "Calc Edit Mode.  Press RET to finish.  Press C-x k RET to cancel.\n"))
  764. X)
  765. X(put 'calc-edit-mode 'mode-class 'special)
  766. X
  767. X(defun calc-show-edit-buffer ()
  768. X  (switch-to-buffer (get-buffer-create "*Calc Edit*"))
  769. X  (if (and (< (window-width) (screen-width))
  770. X       calc-display-trail)
  771. X      (let* ((trail (get-buffer-create "*Calc Trail*"))
  772. X         (win (get-buffer-window trail)))
  773. X    (if win
  774. X        (delete-window win))))
  775. X  (set-buffer-modified-p nil)
  776. X  (goto-char (point-min))
  777. X  (forward-line 1)
  778. X)
  779. X
  780. X(defun calc-edit-finish ()
  781. X  "Finish calc-edit mode.  Parse buffer contents and push them on the stack."
  782. X  (interactive)
  783. X  (or (and (boundp 'calc-original-buffer)
  784. X       (boundp 'calc-edit-handler)
  785. X       (boundp 'calc-restore-trail)
  786. X       (eq major-mode 'calc-edit-mode))
  787. X      (error "This command is valid only in buffers created by calc-edit."))
  788. X  (let ((buf (current-buffer))
  789. X    (original calc-original-buffer)
  790. X    (disp-trail calc-restore-trail))
  791. X    (save-excursion
  792. X      (set-buffer original)
  793. X      (if (not (eq major-mode 'calc-mode))
  794. X      (error "Original calculator buffer has been corrupted.")))
  795. X    (goto-char (point-min))
  796. X    (if (looking-at "Calc Edit")
  797. X    (forward-line 1))
  798. X    (if (buffer-modified-p)
  799. X    (eval calc-edit-handler))
  800. X    (switch-to-buffer original)
  801. X    (kill-buffer buf)
  802. X    (calc-wrapper
  803. X     (if disp-trail
  804. X     (calc-trail-display 1 t))))
  805. X)
  806. X
  807. X(defun calc-finish-stack-edit (num)
  808. X  (let ((buf (current-buffer))
  809. X    (str (buffer-substring (point) (point-max)))
  810. X    (start (point))
  811. X    pos)
  812. X    (while (setq pos (string-match "\n." str))
  813. X      (aset str pos ?\,))
  814. X    (set-buffer calc-original-buffer)
  815. X    (let ((vals (math-read-exprs str)))
  816. X      (if (eq (car-safe vals) 'error)
  817. X      (progn
  818. X        (set-buffer buf)
  819. X        (goto-char (+ start (nth 1 vals)))
  820. X        (error (nth 2 vals))))
  821. X      (calc-wrapper
  822. X       (calc-enter-result num "edit" vals))))
  823. X)
  824. X
  825. X
  826. X
  827. X
  828. X;;; Algebra commands.
  829. X
  830. X(defun calc-a-prefix-help ()
  831. X  (interactive)
  832. X  (calc-do-prefix-help
  833. X   '("Simplify, Extended-simplify; eXpand, Collect"
  834. X     "Derivative, Integral, Taylor; suBstitute; Rewrite"
  835. X     "SHIFT + Solve; Integral-limit")
  836. X   "algebra" ?a)
  837. X)
  838. X
  839. X(defun calc-simplify ()
  840. X  "Simplify the formula on top of the stack."
  841. X  (interactive)
  842. X  (calc-slow-wrapper
  843. X   (calc-with-default-simplification
  844. X    (calc-enter-result 1 "simp" (math-simplify (calc-top-n 1)))))
  845. X)
  846. X
  847. X(defun calc-simplify-extended ()
  848. X  "Simplify the formula on top of the stack.
  849. XThis allows some \"dangerous\" simplifications, such as \"(a^b)^c -> a^(b c)\"
  850. Xeven if c is a non-integer, and \"arcsin(sin(x)) -> x\"."
  851. X  (interactive)
  852. X  (calc-slow-wrapper
  853. X   (calc-with-default-simplification
  854. X    (calc-enter-result 1 "esmp" (math-simplify-extended (calc-top-n 1)))))
  855. X)
  856. X
  857. X(defun calc-expand (n)
  858. X  "Expand the formula on top of the stack using the distributive law.
  859. XWith a numeric prefix argument, expand only that many times, then stop.
  860. XWith a negative prefix, expand only that many nesting-levels down."
  861. X  (interactive "P")
  862. X  (calc-slow-wrapper
  863. X   (calc-enter-result 1 "expa" (math-expand-tree
  864. X                (calc-top-n 1)
  865. X                (and n (prefix-numeric-value n)))))
  866. X)
  867. X
  868. X(defun calc-collect (var)
  869. X  "Collect terms involving a given variable (or sub-expression).
  870. XThe result will be expressed like a polynomial.
  871. XIf you enter a blank line, top of stack is the variable, next-to-top is expr."
  872. X  (interactive "sCollect terms involving: ")
  873. X  (calc-slow-wrapper
  874. X   (if (equal var "")
  875. X       (calc-enter-result 2 "clct" (math-collect-terms (calc-top-n 2)
  876. X                               (calc-top-n 1)))
  877. X     (let ((var (math-read-expr var)))
  878. X       (if (eq (car-safe var) 'error)
  879. X       (error "Bad format in expression: %s" (nth 1 var)))
  880. X       (calc-enter-result 1 "clct" (math-collect-terms (calc-top-n 1)
  881. X                               var)))))
  882. X)
  883. X
  884. X(defun calc-substitute (&optional oldname newname)
  885. X  "Substitute all occurrences of a given sub-expression with another.
  886. XIf you enter a blank line for \"old\", top of stack is the new expr,
  887. Xnext-to-top is the old expr, and third is the target expr.
  888. XIf you enter a blank line for \"new\" only, top of stack is the new
  889. Xexpr and next-to-top is the target expr."
  890. X  (interactive "sSubstitute old: ")
  891. X  (calc-slow-wrapper
  892. X   (let (old new (num 1) expr)
  893. X     (if (or (equal oldname "") (null oldname))
  894. X     (setq new (calc-top-n 1)
  895. X           old (calc-top-n 2)
  896. X           expr (calc-top-n 3)
  897. X           num 3)
  898. X       (or newname
  899. X       (setq newname (read-string (concat "Substitute old: "
  900. X                          oldname
  901. X                          ", new: ")
  902. X                      oldname)))
  903. X       (if (or (equal newname "") (null newname))
  904. X       (setq new (calc-top-n 1)
  905. X         expr (calc-top-n 2)
  906. X         num 2)
  907. X     (setq new (if (stringp newname) (math-read-expr newname) newname))
  908. X     (if (eq (car-safe new) 'error)
  909. X         (error "Bad format in expression: %s" (nth 1 new)))
  910. X     (setq expr (calc-top-n 1)))
  911. X       (setq old (if (stringp oldname) (math-read-expr oldname) oldname))
  912. X       (if (eq (car-safe old) 'error)
  913. X       (error "Bad format in expression: %s" (nth 1 old)))
  914. X       (or (math-expr-contains expr old)
  915. X       (error "No occurrences found.")))
  916. X     (calc-enter-result num "sbst" (math-expr-subst expr old new))))
  917. X)
  918. X
  919. X(defun calc-rewrite (rules many)
  920. X  "Perform substitutions in an expression using pattern-based rewrite rules.
  921. XThis command prompts for the rule(s) to use, which should be either a
  922. Xvector of the form [LHS, RHS] or [LHS, RHS, COND], or a vector of such
  923. Xvectors, or a variable which contains a rules vector.  If you enter a
  924. Xblank line, the rules are taken from top-of-stack, expr from next-to-top.
  925. XIn each rule, LHS is a formula in which each unique variable name stands
  926. Xfor any sub-expression, RHS is a formula typically also containing these
  927. Xvariables, and COND is an optional formula which specifies a condition.
  928. XA rule applies to an expression if the LHS is the same as the expression
  929. Xwhere each variable in LHS corresponds to some sub-expression, and if COND
  930. Xevaluates to a non-zero real number (under those assignments of the
  931. Xvariables).  If so, the expression is replaced by RHS with any variables
  932. Xthat occur in LHS expanded.
  933. XBy default, the rules are applied once to the any part of the expression
  934. Xwhich matches (but preferably to the whole expression).  With a positive
  935. Xnumeric prefix argument, the rules are applied up to that many times, or
  936. Xuntil no further changes can be made.  With a negative prefix argument,
  937. Xthe rules are applied that many times but only at the top level of the
  938. Xexpression."
  939. X  (interactive "sRewrite rule(s): \np")
  940. X  (calc-slow-wrapper
  941. X   (let (n expr)
  942. X     (if (or (null rules) (equal rules ""))
  943. X     (setq expr (calc-top-n 2)
  944. X           rules (calc-top-n 1)
  945. X           n 2)
  946. X       (setq rules (if (stringp rules) (math-read-expr rules) rules))
  947. X       (if (eq (car-safe rules) 'error)
  948. X       (error "Bad format in expression: %s" (nth 1 rules)))
  949. X       (setq expr (calc-top-n 1)
  950. X         n 1))
  951. X     (and (eq many 0) (setq many 25))
  952. X     (calc-enter-result n "rwrt" (math-rewrite expr rules many))))
  953. X)
  954. X
  955. X(defun calc-derivative (var)
  956. X  "Differentiate the formula on top of the stack with respect to a variable.
  957. XIf you enter a blank line, top of stack is the variable, next-to-top is expr.
  958. XWith Hyperbolic flag, performs a total derivative: all variables are
  959. Xconsidered to be inter-dependent.  Otherwise, all variables except VAR
  960. Xare treated as constant."
  961. X  (interactive "sDifferentiate with respect to: ")
  962. X  (calc-slow-wrapper
  963. X   (let ((func (if (calc-is-hyperbolic) 'calcFunc-tderiv 'calcFunc-deriv)))
  964. X     (if (equal var "")
  965. X     (calc-enter-result 2 "derv" (list func
  966. X                       (calc-top-n 2)
  967. X                       (calc-top-n 1)))
  968. X       (let ((var (math-read-expr var)))
  969. X     (if (eq (car-safe var) 'error)
  970. X         (error "Bad format in expression: %s" (nth 1 var)))
  971. X     (calc-enter-result 1 "derv" (list func
  972. X                       (calc-top-n 1)
  973. X                       var))))))
  974. X)
  975. X
  976. X(defun calc-integral (var)
  977. X  "Integrate the formula on top of the stack with respect to a variable.
  978. XThis computes an indefinite integral.
  979. XIf you enter a blank line, top of stack is the variable, next-to-top is expr."
  980. X  (interactive "sIntegration variable: ")
  981. X  (calc-slow-wrapper
  982. X   (if (equal var "")
  983. X       (calc-enter-result 2 "intg" (list 'calcFunc-integ
  984. X                     (calc-top-n 2)
  985. X                     (calc-top-n 1)))
  986. X     (let ((var (math-read-expr var)))
  987. X       (if (eq (car-safe var) 'error)
  988. X       (error "Bad format in expression: %s" (nth 1 var)))
  989. X       (calc-enter-result 1 "intg" (list 'calcFunc-integ
  990. X                     (calc-top-n 1)
  991. X                     var)))))
  992. X)
  993. X
  994. X(defun calc-integral-limit (n)
  995. X  "Display current integral limit, or set the limit to N levels."
  996. X  (interactive "P")
  997. X  (calc-wrapper
  998. X   (if (consp n)
  999. X       (calc-pop-push-record 0 "prec" calc-integral-limit)
  1000. X     (if (and (integerp n) (> n 0))
  1001. X     (progn
  1002. X       (setq calc-integral-limit (prefix-numeric-value n))
  1003. X       (calc-record calc-integral-limit "ilim")))
  1004. X     (message "Integration nesting limit is %d levels." calc-integral-limit)))
  1005. X)
  1006. X
  1007. X(defun calc-solve-for (var)
  1008. X  "Solve an equation for a given variable.
  1009. XIf the top-of-stack is not of the form A = B, it is treated as A = 0.
  1010. XIf you enter a blank line, top of stack is the variable, next-to-top is eqn.
  1011. XWith Hyperbolic flag, finds a fully general solution in which n1, n2, ...
  1012. Xrepresent independent arbitrary integers and s1, s2, ... are independent
  1013. Xarbitrary signs.
  1014. XWith Inverse flag, computes the inverse of the expression, written in terms
  1015. Xof the original variable."
  1016. X  (interactive "sVariable to solve for: ")
  1017. X  (calc-slow-wrapper
  1018. X   (let ((func (if (calc-is-inverse)
  1019. X           (if (calc-is-hyperbolic) 'calcFunc-ffinv 'calcFunc-finv)
  1020. X         (if (calc-is-hyperbolic) 'calcFunc-fsolve 'calcFunc-solve))))
  1021. X     (if (equal var "")
  1022. X     (calc-enter-result 2 "solv" (list func
  1023. X                       (calc-top-n 2)
  1024. X                       (calc-top-n 1)))
  1025. X       (let ((var (math-read-expr var)))
  1026. X     (if (eq (car-safe var) 'error)
  1027. X         (error "Bad format in expression: %s" (nth 1 var)))
  1028. X     (calc-enter-result 1 "solv" (list func
  1029. X                       (calc-top-n 1)
  1030. X                       var))))))
  1031. X)
  1032. X
  1033. X(defun calc-taylor (var nterms)
  1034. X  "Compute the Taylor expansion of a formula."
  1035. X  (interactive "sTaylor expansion variable: \nNNumber of terms: ")
  1036. X  (calc-slow-wrapper
  1037. X   (let ((var (math-read-expr var)))
  1038. X     (if (eq (car-safe var) 'error)
  1039. X     (error "Bad format in expression: %s" (nth 1 var)))
  1040. X     (calc-enter-result 1 "tylr" (list 'calcFunc-taylor
  1041. X                       (calc-top-n 1)
  1042. X                       var
  1043. X                       nterms))))
  1044. X)
  1045. X
  1046. X
  1047. X(defun calc-equal-to (arg)
  1048. X  "Return 1 if numbers are equal, 0 if they are unequal."
  1049. X  (interactive "P")
  1050. X  (calc-wrapper
  1051. X   (calc-binary-op "eq" 'calcFunc-eq arg))
  1052. X)
  1053. X
  1054. X(defun calc-not-equal-to (arg)
  1055. X  "Return 1 if numbers are unequal, 0 if they are equal."
  1056. X  (interactive "P")
  1057. X  (calc-wrapper
  1058. X   (calc-binary-op "neq" 'calcFunc-neq arg))
  1059. X)
  1060. X
  1061. X(defun calc-less-than (arg)
  1062. X  "Return 1 if numbers are less, 0 if they are not less."
  1063. X  (interactive "P")
  1064. X  (calc-wrapper
  1065. X   (calc-binary-op "lt" 'calcFunc-lt arg))
  1066. X)
  1067. X
  1068. X(defun calc-greater-than (arg)
  1069. X  "Return 1 if numbers are greater, 0 if they are not greater."
  1070. X  (interactive "P")
  1071. X  (calc-wrapper
  1072. X   (calc-binary-op "gt" 'calcFunc-gt arg))
  1073. X)
  1074. X
  1075. X(defun calc-less-equal (arg)
  1076. X  "Return 1 if numbers are less than or equal to, 0 if they are not leq."
  1077. X  (interactive "P")
  1078. X  (calc-wrapper
  1079. X   (calc-binary-op "leq" 'calcFunc-leq arg))
  1080. X)
  1081. X
  1082. X(defun calc-greater-equal (arg)
  1083. X  "Return 1 if numbers are greater than or equal to, 0 if they are not geq."
  1084. X  (interactive "P")
  1085. X  (calc-wrapper
  1086. X   (calc-binary-op "geq" 'calcFunc-geq arg))
  1087. X)
  1088. X
  1089. X(defun calc-in-set (arg)
  1090. X  "Return 1 if a number is in the set specified by a vector or interval.
  1091. XReturn 0 if it is not in the set."
  1092. X  (interactive "P")
  1093. X  (calc-wrapper
  1094. X   (calc-binary-op "in" 'calcFunc-in arg))
  1095. X)
  1096. X
  1097. X(defun calc-logical-and (arg)
  1098. X  "Return 1 if both numbers are non-zero, 0 if either is zero."
  1099. X  (interactive "P")
  1100. X  (calc-wrapper
  1101. X   (calc-binary-op "land" 'calcFunc-land arg 1))
  1102. X)
  1103. X
  1104. X(defun calc-logical-or (arg)
  1105. X  "Return 1 if either number is non-zero, 0 if both are zero."
  1106. X  (interactive "P")
  1107. X  (calc-wrapper
  1108. X   (calc-binary-op "lor" 'calcFunc-lor arg 0))
  1109. X)
  1110. X
  1111. X(defun calc-logical-not (arg)
  1112. X  "Return 1 if a number is zero, 0 if it is non-zero."
  1113. X  (interactive "P")
  1114. X  (calc-wrapper
  1115. X   (calc-unary-op "lnot" 'calcFunc-lnot arg))
  1116. X)
  1117. X
  1118. X
  1119. X
  1120. X
  1121. X;;; b-prefix binary commands.
  1122. X
  1123. X(defun calc-b-prefix-help ()
  1124. X  (interactive)
  1125. X  (calc-do-prefix-help
  1126. X   '("And, Or, Xor, Diff, Not; Wordsize, Clip"
  1127. X     "Lshift, Rshift-logical, rShift-arith; SHIFT + Rotate")
  1128. X   "binary" ?b)
  1129. X)
  1130. X
  1131. X(defun calc-and (n)
  1132. X  "Compute the bitwise binary AND of the top two elements on the stack."
  1133. X  (interactive "P")
  1134. X  (calc-slow-wrapper
  1135. X   (calc-enter-result 2 "and"
  1136. X              (append '(calcFunc-and)
  1137. X                  (calc-top-list-n 2)
  1138. X                  (and n (list (prefix-numeric-value n))))))
  1139. X)
  1140. X
  1141. X(defun calc-or (n)
  1142. X  "Compute the bitwise binary OR of the top two elements on the stack."
  1143. X  (interactive "P")
  1144. X  (calc-slow-wrapper
  1145. X   (calc-enter-result 2 "or"
  1146. X              (append '(calcFunc-or)
  1147. X                  (calc-top-list-n 2)
  1148. X                  (and n (list (prefix-numeric-value n))))))
  1149. X)
  1150. X
  1151. X(defun calc-xor (n)
  1152. X  "Compute the bitwise binary XOR of the top two elements on the stack."
  1153. X  (interactive "P")
  1154. X  (calc-slow-wrapper
  1155. X   (calc-enter-result 2 "xor"
  1156. X              (append '(calcFunc-xor)
  1157. X                  (calc-top-list-n 2)
  1158. X                  (and n (list (prefix-numeric-value n))))))
  1159. X)
  1160. X
  1161. X(defun calc-diff (n)
  1162. X  "Compute the bitwise binary AND-NOT of the top two elements on the stack."
  1163. X  (interactive "P")
  1164. X  (calc-slow-wrapper
  1165. X   (calc-enter-result 2 "diff"
  1166. X              (append '(calcFunc-diff)
  1167. X                  (calc-top-list-n 2)
  1168. X                  (and n (list (prefix-numeric-value n))))))
  1169. X)
  1170. X
  1171. X(defun calc-not (n)
  1172. X  "Compute the bitwise binary NOT of the top element on the stack.
  1173. XA prefix argument specifies word size to use for this operation (instead of
  1174. Xthe default).  The result is clipped to fit in the word size."
  1175. X  (interactive "P")
  1176. X  (calc-slow-wrapper
  1177. X   (calc-enter-result 1 "not"
  1178. X              (append '(calcFunc-not)
  1179. X                  (calc-top-list-n 1)
  1180. X                  (and n (list (prefix-numeric-value n))))))
  1181. X)
  1182. X
  1183. X(defun calc-shift-binary (n)
  1184. X  "Shift the top element on the stack one bit right in binary (arithmetically).
  1185. XWith a numeric prefix argument, shift N bits left.
  1186. XWith a negative prefix argument, arithmetically shift -N bits right.
  1187. XThe result is clipped to the current word size."
  1188. X  (interactive "P")
  1189. X  (calc-slow-wrapper
  1190. X   (calc-enter-result 1 "ash"
  1191. X              (append '(calcFunc-ash)
  1192. X                  (calc-top-list-n 1)
  1193. X                  (and n (list (prefix-numeric-value n))))))
  1194. X)
  1195. X
  1196. X(defun calc-lshift-binary (n)
  1197. X  "Shift the top element on the stack one bit left in binary.
  1198. XWith a numeric prefix argument, shift N bits left.
  1199. XWith a negative prefix argument, logically shift -N bits right.
  1200. XThe result is clipped to the current word size."
  1201. X  (interactive "P")
  1202. X  (calc-slow-wrapper
  1203. X   (calc-enter-result 1 "lsh"
  1204. X              (append '(calcFunc-lsh)
  1205. X                  (calc-top-list-n 1)
  1206. X                  (and n (list (prefix-numeric-value n))))))
  1207. X)
  1208. X
  1209. X(defun calc-rshift-binary (n)
  1210. X  "Shift the top element on the Calculator stack one bit right in binary.
  1211. XWith a numeric prefix argument, logically shift N bits right.
  1212. XWith a negative prefix argument, shift -N bits left.
  1213. XThe result is clipped to the current word size."
  1214. X  (interactive "P")
  1215. X  (calc-slow-wrapper
  1216. X   (calc-enter-result 1 "rsh"
  1217. X              (append '(calcFunc-rsh)
  1218. X                  (calc-top-list-n 1)
  1219. X                  (and n (list (prefix-numeric-value n))))))
  1220. X)
  1221. X
  1222. X(defun calc-rotate-binary (n)
  1223. X  "Rotate the top element on the Calculator stack one bit left in binary.
  1224. XWith a numeric prefix argument, rotate N bits left.
  1225. XWith a negative prefix argument, rotate -N bits right.
  1226. XThe result is clipped to the current word size."
  1227. X  (interactive "P")
  1228. X  (calc-slow-wrapper
  1229. X   (calc-enter-result 1 "rot"
  1230. X              (append '(calcFunc-rot)
  1231. X                  (calc-top-list-n 1)
  1232. X                  (and n (list (prefix-numeric-value n))))))
  1233. X)
  1234. X
  1235. X(defun calc-clip (n)
  1236. X  "Clip the integer at the top of the stack to the current binary word size.
  1237. XA prefix argument specifies an alternate word size to use."
  1238. X  (interactive "P")
  1239. X  (calc-slow-wrapper
  1240. X   (calc-enter-result 1 "clip"
  1241. X              (append '(calcFunc-clip)
  1242. X                  (calc-top-list-n 1)
  1243. X                  (and n (list (prefix-numeric-value n))))))
  1244. X)
  1245. X
  1246. X(defun calc-word-size (n)
  1247. X  "Display current word size for Calculator binary operations, or set to N bits.
  1248. X\(All other bitwise operations accept a prefix argument to override this
  1249. Xdefault size.)
  1250. XIf N is negative, use |N|-bit, 2's complement arithmetic."
  1251. X  (interactive "P")
  1252. X  (calc-wrapper
  1253. X   (if n
  1254. X       (progn
  1255. X     (setq calc-word-size (prefix-numeric-value n)
  1256. X           calc-previous-modulo (math-power-of-2
  1257. X                     (math-abs calc-word-size)))
  1258. X     (if calc-leading-zeros
  1259. X         (calc-refresh))))
  1260. X   (if (< calc-word-size 0)
  1261. X       (message "Binary word size is %d bits (2's complement)."
  1262. X        (- calc-word-size))
  1263. X     (message "Binary word size is %d bits." calc-word-size)))
  1264. X)
  1265. X
  1266. X
  1267. X
  1268. X
  1269. X;;; Conversions.
  1270. X
  1271. X(defun calc-c-prefix-help ()
  1272. X  (interactive)
  1273. X  (calc-do-prefix-help
  1274. X   '("Deg, Rad, HMS; Float; Polar; Clean, 1, 2, 3"
  1275. X     "SHIFT + Fraction")
  1276. X   "convert" ?c)
  1277. X)
  1278. X
  1279. X(defun calc-clean (n)
  1280. X  "Clean up the number at the top of the Calculator stack.
  1281. XRe-round to current precision, or to that specified by a prefix argument.
  1282. XThis temporarily cancels no-simplify mode, if necessary."
  1283. X  (interactive "P")
  1284. X  (calc-slow-wrapper
  1285. X   (calc-with-default-simplification
  1286. X    (calc-enter-result 1 "cln"
  1287. X               (if n
  1288. X               (let ((n (prefix-numeric-value n)))
  1289. X                 (list 'calcFunc-clean
  1290. X                   (calc-top-n 1)
  1291. X                   (if (< n 0)
  1292. X                       (+ n calc-internal-prec)
  1293. X                     n)))
  1294. X             (list 'calcFunc-clean (calc-top-n 1))))))
  1295. X)
  1296. X
  1297. X(defun calc-clean-1 ()
  1298. X  "Clean up the number on the top of the stack by rounding off one digit."
  1299. X  (interactive)
  1300. X  (calc-clean -1)
  1301. X)
  1302. X
  1303. X(defun calc-clean-2 ()
  1304. X  "Clean up the number on the top of the stack by rounding off two digits."
  1305. X  (interactive)
  1306. X  (calc-clean -2)
  1307. X)
  1308. X
  1309. X(defun calc-clean-3 ()
  1310. X  "Clean up the number on the top of the stack by rounding off three digits."
  1311. X  (interactive)
  1312. X  (calc-clean -3)
  1313. X)
  1314. X
  1315. X(defun calc-float (arg)
  1316. X  "Convert the top element of the Calculator stack to floating-point form."
  1317. X  (interactive "P")
  1318. X  (calc-slow-wrapper
  1319. X   (calc-unary-op "flt" 'calcFunc-float arg))
  1320. X)
  1321. X
  1322. X(defun calc-fraction (arg)
  1323. X  "Convert the top element of the Calculator stack to fractional form.
  1324. XFor floating-point arguments, the fraction is exactly equivalent within
  1325. Xthe limits of the current precision.
  1326. XIf a numeric prefix N is supplied, it is used as a tolerance value.
  1327. XIf N is zero, top-of-stack contains a tolerance value.
  1328. XIf the tolerance is a positive integer, the fraction will be accurate to
  1329. Xwithin that many significant figures.
  1330. XIf the tolerance is a non-positive integer, the fraction will be accurate to
  1331. Xwithin that many figures less than the current precision.
  1332. XIf the tolerance is a floating-point number, the fraction will be accurate
  1333. Xto within that absolute value."
  1334. X  (interactive "P")
  1335. X  (calc-slow-wrapper
  1336. X   (if (eq arg 0)
  1337. X       (calc-enter-result 2 "frac" (list 'calcFunc-frac
  1338. X                     (calc-top-n 2)
  1339. X                     (calc-top-n 1)))
  1340. X     (calc-enter-result 1 "frac" (list 'calcFunc-frac
  1341. X                       (calc-top-n 1)
  1342. X                       (prefix-numeric-value (or arg 0))))))
  1343. X)
  1344. X
  1345. X(defun calc-to-hms (arg)
  1346. X  "Convert the top element of the stack to hours-minutes-seconds form.
  1347. XNumber is interpreted as degrees or radians according to current mode."
  1348. X  (interactive "P")
  1349. X  (calc-wrapper
  1350. X   (if (calc-is-inverse)
  1351. X       (if (eq calc-angle-mode 'rad)
  1352. X       (calc-unary-op ">rad" 'calcFunc-rad arg)
  1353. X     (calc-unary-op ">deg" 'calcFunc-deg arg))
  1354. X     (calc-unary-op ">hms" 'calcFunc-hms arg)))
  1355. X)
  1356. X
  1357. X(defun calc-from-hms (arg)
  1358. X  "Convert the top element of the stack from hours-minutes-seconds form."
  1359. X  (interactive "P")
  1360. X  (calc-invert-func)
  1361. X  (calc-to-hms arg)
  1362. X)
  1363. X
  1364. X(defun calc-to-degrees (arg)
  1365. X  "Convert the top element of the stack from radians or HMS to degrees."
  1366. X  (interactive "P")
  1367. X  (calc-wrapper
  1368. X   (calc-unary-op ">deg" 'calcFunc-deg arg))
  1369. X)
  1370. X
  1371. X(defun calc-to-radians (arg)
  1372. X  "Convert the top element of the stack from degrees or HMS to radians."
  1373. X  (interactive "P")
  1374. X  (calc-wrapper
  1375. X   (calc-unary-op ">rad" 'calcFunc-rad arg))
  1376. X)
  1377. X
  1378. X(defun calc-polar ()
  1379. X  "Convert the top element of the stack to polar complex form."
  1380. X  (interactive)
  1381. X  (calc-slow-wrapper
  1382. X   (let ((arg (calc-top-n 1)))
  1383. X     (if (or (calc-is-inverse)
  1384. X         (eq (car-safe arg) 'polar))
  1385. X     (calc-enter-result 1 "p-r" (list 'calcFunc-rect arg))
  1386. X       (calc-enter-result 1 "r-p" (list 'calcFunc-polar arg)))))
  1387. X)
  1388. X
  1389. X
  1390. X
  1391. X;;; d-prefix mode commands.
  1392. X
  1393. X(defun calc-d-prefix-help ()
  1394. X  (interactive)
  1395. X  (calc-do-prefix-help
  1396. X   '("Group, \",\"; Normal, Fix, Sci, Eng, \".\""
  1397. X     "Radix, Zeros, 2, 8, 0, 6; Over; Hms; Complex, I, J"
  1398. X     "Why; Line-nums, line-Breaks; <, =, > (justify)"
  1399. X     "Truncate, [, ]; ` (align); ~ (refresh)"
  1400. X     "SHIFT + language: Normal, One-line, Big, Unformatted"
  1401. X     "SHIFT + language: C, Pascal, Fortran, TeX, Mathematica")
  1402. X   "display" ?d)
  1403. X)
  1404. X
  1405. X(defun calc-radix (n)
  1406. X  "Set the display radix for integers and rationals to N, from 2 to 36."
  1407. X  (interactive "NDisplay radix (2-36): ")
  1408. X  (calc-wrapper
  1409. X   (if (and (>= n 2) (<= n 36))
  1410. X       (progn
  1411. X     (setq calc-number-radix n)
  1412. X     (setq-default calc-number-radix n)))  ; so minibuffer sees it
  1413. X   (calc-refresh)
  1414. X   (message "Number radix is %d." calc-number-radix))
  1415. X)
  1416. X
  1417. X(defun calc-decimal-radix ()
  1418. X  "Set the display radix for integers and rationals to decimal."
  1419. X  (interactive)
  1420. X  (calc-radix 10)
  1421. X)
  1422. X
  1423. X(defun calc-binary-radix ()
  1424. X  "Set the display radix for integers and rationals to binary."
  1425. X  (interactive)
  1426. X  (calc-radix 2)
  1427. X)
  1428. X
  1429. X(defun calc-octal-radix ()
  1430. X  "Set the display radix for integers and rationals to octal."
  1431. X  (interactive)
  1432. X  (calc-radix 8)
  1433. X)
  1434. X
  1435. X(defun calc-hex-radix ()
  1436. X  "Set the display radix for integers and rationals to hex."
  1437. X  (interactive)
  1438. X  (calc-radix 16)
  1439. X)
  1440. X
  1441. X(defun calc-leading-zeros (n)
  1442. X  "Toggle display of leading zeros in integers."
  1443. X  (interactive "P")
  1444. X  (calc-wrapper
  1445. X   (setq calc-leading-zeros (if n
  1446. X                (> (prefix-numeric-value n) 0)
  1447. X                  (not calc-leading-zeros)))
  1448. X   (calc-refresh))
  1449. X)
  1450. X
  1451. X(defun calc-line-numbering (n)
  1452. X  "Toggle display of line numbers in the Calculator stack.
  1453. XWith positive numeric prefix, turn mode on.
  1454. XWith 0 or negative prefix, turn mode off."
  1455. X  (interactive "P")
  1456. X  (calc-wrapper
  1457. X   (setq calc-line-numbering (if n
  1458. X                 (> (prefix-numeric-value n) 0)
  1459. X                   (not calc-line-numbering)))
  1460. X   (calc-refresh))
  1461. X)
  1462. X
  1463. X(defun calc-line-breaking (n)
  1464. X  "Toggle breaking of long values across multiple lines in Calculator stack.
  1465. XWith positive numeric prefix, turn mode on.
  1466. XWith 0 or negative prefix, turn mode off."
  1467. X  (interactive "P")
  1468. X  (calc-wrapper
  1469. X   (setq calc-line-breaking (if n
  1470. X                (> (prefix-numeric-value n) 0)
  1471. X                  (not calc-line-breaking)))
  1472. X   (calc-refresh))
  1473. X)
  1474. X
  1475. X(defun calc-display-strings (n)
  1476. X  "Toggle display of vectors of byte-sized integers as strings.
  1477. XWith positive numeric prefix, turn mode on.
  1478. XWith 0 or negative prefix, turn mode off."
  1479. X  (interactive "P")
  1480. X  (calc-wrapper
  1481. X   (setq calc-display-strings (if n
  1482. X                  (> (prefix-numeric-value n) 0)
  1483. X                (not calc-display-strings)))
  1484. X   (calc-refresh))
  1485. X)
  1486. X
  1487. X(defun calc-left-justify ()
  1488. X  "Display stack entries left-justified in the window."
  1489. X  (interactive)
  1490. X  (calc-wrapper
  1491. X   (setq calc-display-just nil)
  1492. X   (calc-refresh))
  1493. X)
  1494. X
  1495. X(defun calc-center-justify ()
  1496. X  "Display stack entries centered in the window."
  1497. X  (interactive)
  1498. X  (calc-wrapper
  1499. X   (setq calc-display-just 'center)
  1500. X   (calc-refresh))
  1501. X)
  1502. X
  1503. X(defun calc-right-justify ()
  1504. X  "Display stack entries right-justified in the window."
  1505. X  (interactive)
  1506. X  (calc-wrapper
  1507. X   (setq calc-display-just 'right)
  1508. X   (calc-refresh))
  1509. X)
  1510. X
  1511. X(defun calc-auto-why (n)
  1512. X  "Toggle automatic explanations of why results were left in symbolic form.
  1513. XThis can always be requested explicitly with the calc-why command.
  1514. XWith positive numeric prefix, turn mode on.
  1515. XWith 0 or negative prefix, turn mode off."
  1516. X  (interactive "P")
  1517. X  (calc-wrapper
  1518. X   (setq calc-auto-why (if n
  1519. X               (> (prefix-numeric-value n) 0)
  1520. X             (not calc-auto-why)))
  1521. X   (if calc-auto-why
  1522. X       (message "Automatically executing a \"why\" command when appropriate.")
  1523. X     (message "User must execute a \"why\" command to explain unsimplified results.")))
  1524. X)
  1525. X
  1526. X(defun calc-group-digits (n)
  1527. X  "Toggle grouping of digits, or set group size to N digits.
  1528. XWith numeric prefix 0, display current setting.
  1529. XWith numeric prefix -1, disable grouping.
  1530. XWith other negative prefix, group after decimal point as well as before."
  1531. X  (interactive "P")
  1532. X  (calc-wrapper
  1533. X   (if (consp n)
  1534. X       (calc-pop-push-record 0 "grp" (cond ((null calc-group-digits) -1)
  1535. X                       ((eq calc-group-digits t)
  1536. X                        (if (memq calc-number-radix
  1537. X                              '(2 16)) 4 3))
  1538. X                       (t calc-group-digits)))
  1539. X     (if n
  1540. X     (let ((n (prefix-numeric-value n)))
  1541. X       (cond ((or (> n 0) (< n -1))
  1542. X          (setq calc-group-digits n))
  1543. X         ((= n -1)
  1544. X          (setq calc-group-digits nil))))
  1545. X       (setq calc-group-digits (not calc-group-digits)))
  1546. X     (calc-refresh)
  1547. X     (cond ((null calc-group-digits)
  1548. X        (message "Grouping is off."))
  1549. X       ((integerp calc-group-digits)
  1550. X        (message "Grouping every %d digits." (math-abs calc-group-digits)))
  1551. X       (t
  1552. X        (message "Grouping is on.")))))
  1553. X)
  1554. X
  1555. X(defun calc-group-char (ch)
  1556. X  "Set the character to be used for grouping digits in calc-group-digits mode."
  1557. X  (interactive "cGrouping character: ")
  1558. X  (calc-wrapper
  1559. X   (or (>= ch 32)
  1560. X       (error "Control characters not allowed for grouping"))
  1561. X   (setq calc-group-char (char-to-string ch))
  1562. X   (if calc-group-digits
  1563. X       (calc-refresh)))
  1564. X)
  1565. X
  1566. X(defun calc-point-char (ch)
  1567. X  "Set the character to be used as the decimal point."
  1568. X  (interactive "cCharacter to use as decimal point: ")
  1569. X  (calc-wrapper
  1570. X   (or (>= ch 32)
  1571. X       (error "Control characters not allowed as decimal point"))
  1572. X   (setq calc-point-char (char-to-string ch))
  1573. X   (calc-refresh))
  1574. X)
  1575. X
  1576. X(defun calc-normal-notation (n)
  1577. X  "Set normal (floating) notation for floating-point numbers.
  1578. XWith argument N > 0, round to N significant digits.
  1579. XWith argument -N < 0, round to current precision - N significant digits."
  1580. X  (interactive "P")
  1581. X  (calc-wrapper
  1582. X   (setq calc-float-format (list 'float
  1583. X                 (if n (prefix-numeric-value n) 0)))
  1584. X   (setq calc-full-float-format (list 'float 0))
  1585. X   (calc-refresh))
  1586. X)
  1587. X
  1588. X(defun calc-fix-notation (n)
  1589. X  "Set fixed-point notation for floating-point numbers."
  1590. X  (interactive "NDigits after decimal point: ")
  1591. X  (calc-wrapper
  1592. X   (let ((n (prefix-numeric-value n)))
  1593. X     (setq calc-float-format (list 'fix n)))
  1594. X   (setq calc-full-float-format (list 'float 0))
  1595. X   (calc-refresh))
  1596. X)
  1597. X
  1598. X(defun calc-sci-notation (n)
  1599. X  "Set scientific notation for floating-point numbers.
  1600. XWith argument N > 0, round to N significant digits.
  1601. XWith argument -N < 0, round to current precision - N significant digits."
  1602. X  (interactive "P")
  1603. X  (calc-wrapper
  1604. X   (let ((n (if n (prefix-numeric-value n) 0)))
  1605. X     (setq calc-float-format (list 'sci n)))   ; (if (> n 0) (1+ n) n)
  1606. X   (setq calc-full-float-format (list 'sci 0))
  1607. X   (calc-refresh))
  1608. X)
  1609. X
  1610. X(defun calc-eng-notation (n)
  1611. X  "Set engineering notation for floating-point numbers.
  1612. XWith argument N > 0, round to N significant digits.
  1613. XWith argument -N < 0, round to current precision - N significant digits."
  1614. X  (interactive "P")
  1615. X  (calc-wrapper
  1616. X   (let ((n (if n (prefix-numeric-value n) 0)))
  1617. X     (setq calc-float-format (list 'eng n)))
  1618. X   (setq calc-full-float-format (list 'eng 0))
  1619. X   (calc-refresh))
  1620. X)
  1621. X
  1622. X(defun calc-complex-notation ()
  1623. X  "Set (x,y) notation for display of complex numbers."
  1624. X  (interactive)
  1625. X  (calc-wrapper
  1626. X   (setq calc-complex-format nil)
  1627. X   (calc-refresh))
  1628. X)
  1629. X
  1630. X(defun calc-i-notation ()
  1631. X  "Set x+yi notation for display of complex numbers."
  1632. X  (interactive)
  1633. X  (calc-wrapper
  1634. X   (setq calc-complex-format 'i)
  1635. X   (calc-refresh))
  1636. X)
  1637. X
  1638. X(defun calc-j-notation ()
  1639. X  "Set x+yj notation for display of complex numbers."
  1640. X  (interactive)
  1641. X  (calc-wrapper
  1642. X   (setq calc-complex-format 'j)
  1643. X   (calc-refresh))
  1644. X)
  1645. X
  1646. X(defun calc-over-notation (fmt)
  1647. X  "Set notation used for fractions.  Argument should be one of :, ::, /, //, :/.
  1648. X\(During numeric entry, the : key is always used.)"
  1649. X  (interactive "sFraction separator (:, ::, /, //, :/): ")
  1650. X  (calc-wrapper
  1651. X   (if (string-match "\\`[^ ][^ ]?\\'" fmt)
  1652. X       (setq calc-frac-format fmt)
  1653. X     (error "Bad fraction separator format."))
  1654. X   (calc-refresh))
  1655. X)
  1656. X
  1657. X(defun calc-slash-notation (n)
  1658. X  "Set \"a/b\" notation for fractions.
  1659. XWith a prefix argument, set \"a/b/c\" notation."
  1660. X  (interactive "P")
  1661. X  (calc-wrapper
  1662. X   (setq calc-frac-format (if n "//" "/")))
  1663. X)
  1664. X
  1665. X(defun calc-hms-notation (fmt)
  1666. X  "Set notation used for hours-minutes-seconds values.
  1667. XArgument should be something like: hms, deg m s, o'\".
  1668. X\(During numeric entry, @ ' \", o ' \", or h ' \" format must be used.)"
  1669. X  (interactive "sHours-minutes-seconds format (hms, @ ' \", etc.): ")
  1670. X  (calc-wrapper
  1671. X   (if (string-match "\\`\\([^,; ]+\\)\\([,; ]*\\)\\([^,; ]\\)\\([,; ]*\\)\\([^,; ]\\)\\'" fmt)
  1672. X       (progn
  1673. X     (setq calc-hms-format (concat "%s" (math-match-substring fmt 1)
  1674. X                       (math-match-substring fmt 2)
  1675. X                       "%s" (math-match-substring fmt 3)
  1676. X                       (math-match-substring fmt 4)
  1677. X                       "%s" (math-match-substring fmt 5)))
  1678. X     (setq-default calc-hms-format calc-hms-format))  ; for minibuffer
  1679. X     (error "Bad hours-minutes-seconds format."))
  1680. X   (calc-refresh))
  1681. X)
  1682. X
  1683. X(defun calc-truncate-stack (n &optional rel)
  1684. X  "Treat cursor line as \"top of stack\" for all further operations.
  1685. XObjects below this line are frozen, but still displayed."
  1686. X  (interactive "P")
  1687. X  (calc-wrapper
  1688. X   (let ((oldtop calc-stack-top)
  1689. X     (newtop calc-stack-top))
  1690. X     (calc-record-undo (list 'set 'saved-stack-top calc-stack-top))
  1691. X     (let ((calc-stack-top 0)
  1692. X       (nn (prefix-numeric-value n)))
  1693. X       (setq newtop
  1694. X         (if n
  1695. X         (progn
  1696. X           (if rel
  1697. X               (setq nn (+ oldtop nn))
  1698. X             (if (< nn 0)
  1699. X             (setq nn (+ nn (calc-stack-size)))
  1700. X               (setq nn (1+ nn))))
  1701. X           (if (< nn 1)
  1702. X               1
  1703. X             (if (> nn (calc-stack-size))
  1704. X             (calc-stack-size)
  1705. X               nn)))
  1706. X           (max 1 (calc-locate-cursor-element (point)))))
  1707. X       (if (= newtop oldtop)
  1708. X       ()
  1709. X     (calc-pop-stack 1 oldtop)
  1710. X     (calc-push-list '(top-of-stack) newtop)
  1711. X     (if calc-line-numbering
  1712. X         (calc-refresh))))
  1713. X     (calc-record-undo (list 'set 'saved-stack-top 0))
  1714. X     (setq calc-stack-top newtop)))
  1715. X)
  1716. X
  1717. X(defun calc-truncate-up (n)
  1718. X  (interactive "p")
  1719. X  (calc-truncate-stack n t)
  1720. X)
  1721. X
  1722. X(defun calc-truncate-down (n)
  1723. X  (interactive "p")
  1724. X  (calc-truncate-stack (- n) t)
  1725. X)
  1726. X
  1727. X(defun calc-display-raw ()
  1728. X  (interactive)
  1729. X  (calc-wrapper
  1730. X   (setq calc-display-raw (not (eq calc-display-raw t)))
  1731. X   (calc-refresh)
  1732. X   (if calc-display-raw
  1733. X       (message "Press d ' again to cancel \"raw\" display mode.")))
  1734. X)
  1735. X
  1736. X(defun calc-display-unformatted ()
  1737. X  (interactive)
  1738. X  (calc-wrapper
  1739. X   (setq calc-display-raw (if (eq calc-display-raw 0) nil 0))
  1740. X   (calc-refresh)
  1741. X   (if calc-display-raw
  1742. X       (message "Press d \" again to cancel \"unformatted\" display mode.")))
  1743. X)
  1744. X
  1745. X
  1746. X
  1747. X;;; Alternate entry/display languages.
  1748. X
  1749. X(defun calc-set-language (lang &optional option no-refresh)
  1750. X  (setq calc-language lang
  1751. X    calc-language-option (and option (prefix-numeric-value option))
  1752. X    math-expr-opers (or (get lang 'math-oper-table) math-standard-opers)
  1753. X    math-expr-function-mapping (get lang 'math-function-table)
  1754. X    math-expr-variable-mapping (get lang 'math-variable-table)
  1755. X    calc-language-input-filter (get lang 'math-input-filter)
  1756. X    calc-language-output-filter (get lang 'math-output-filter)
  1757. X    calc-vector-brackets (or (get lang 'math-vector-brackets) "[]")
  1758. X    calc-complex-format (get lang 'math-complex-format)
  1759. X    calc-radix-formatter (get lang 'math-radix-formatter)
  1760. X    calc-function-open (or (get lang 'math-function-open) "(")
  1761. X    calc-function-close (or (get lang 'math-function-close) ")"))
  1762. X  (or no-refresh
  1763. X      (calc-refresh))
  1764. X)
  1765. X
  1766. X(defun calc-normal-language ()
  1767. X  "Set normal entry and display notation."
  1768. X  (interactive)
  1769. X  (calc-wrapper
  1770. X   (calc-set-language nil))
  1771. X)
  1772. X
  1773. X(defun calc-flat-language ()
  1774. X  "Set normal entry and display notation, with one-line display of matrices."
  1775. X  (interactive)
  1776. X  (calc-wrapper
  1777. X   (calc-set-language 'flat))
  1778. X)
  1779. X
  1780. X(defun calc-big-language ()
  1781. X  "Set big-format display notation."
  1782. X  (interactive)
  1783. X  (calc-wrapper
  1784. X   (calc-set-language 'big))
  1785. X)
  1786. X
  1787. X(defun calc-unformatted-language ()
  1788. X  "Set normal entry and display notation with no operators: add(a, mul(b,c))."
  1789. X  (interactive)
  1790. X  (calc-wrapper
  1791. X   (calc-set-language 'unform))
  1792. X)
  1793. X
  1794. X
  1795. X(defun calc-c-language ()
  1796. X  "Set C-language entry and display notation."
  1797. X  (interactive)
  1798. X  (calc-wrapper
  1799. X   (calc-set-language 'c))
  1800. X)
  1801. X
  1802. X(put 'c 'math-oper-table
  1803. X  '( ( "u+"    ident         -1 1000 )
  1804. X     ( "u-"    neg         -1 1000 )
  1805. X     ( "u!"    calcFunc-lnot -1 1000 )
  1806. X     ( "~"     calcFunc-not  -1 1000 )
  1807. X     ( "*"     *         190 191 )
  1808. X     ( "/"     /         190 191 )
  1809. X     ( "%"     %         190 191 )
  1810. X     ( "+"     +         180 181 )
  1811. X     ( "-"     -         180 181 )
  1812. X     ( "<<"    calcFunc-lsh  170 171 )
  1813. X     ( ">>"    calcFunc-rsh  170 171 )
  1814. X     ( "<"     calcFunc-lt   160 161 )
  1815. X     ( ">"     calcFunc-gt   160 161 )
  1816. X     ( "<="    calcFunc-leq  160 161 )
  1817. X     ( ">="    calcFunc-geq  160 161 )
  1818. X     ( "=="    calcFunc-eq   150 151 )
  1819. X     ( "!="    calcFunc-neq  150 151 )
  1820. X     ( "&"     calcFunc-and  140 141 )
  1821. X     ( "^"     calcFunc-xor  131 130 )
  1822. X     ( "|"     calcFunc-or   120 121 )
  1823. X     ( "&&"    calcFunc-land 110 111 )
  1824. X     ( "||"    calcFunc-lor  100 101 )
  1825. X     ( "?"     calcFunc-if    91  90 )
  1826. X     ( "="     calcFunc-assign 81 80 )
  1827. X)) ; should support full assignments
  1828. X
  1829. X(put 'c 'math-function-table
  1830. X  '( ( acos       . calcFunc-arccos )
  1831. X     ( acosh       . calcFunc-arccosh )
  1832. X     ( asin       . calcFunc-arcsin )
  1833. X     ( asinh       . calcFunc-arcsinh )
  1834. SHAR_EOF
  1835. echo "End of part 4"
  1836. echo "File calc-ext.el is continued in part 5"
  1837. echo "5" > s2_seq_.tmp
  1838. exit 0
  1839.