home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume13 / gmcalc / part01 next >
Encoding:
Text File  |  1990-06-05  |  57.2 KB  |  1,645 lines

  1. Newsgroups: comp.sources.misc
  2. From: daveg@csvax.caltech.edu (David Gillespie)
  3. Subject: v13i027: Emacs Calculator 1.01, part 01/19
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 13, Issue 27
  7. Submitted-by: daveg@csvax.caltech.edu (David Gillespie)
  8. Archive-name: gmcalc/part01
  9.  
  10. ---- Cut Here and unpack ----
  11. #!/bin/sh
  12. # shar:    Shell Archiver  (v1.22)
  13. #
  14. # This is part 1 of a multipart archive                                    
  15. # do not concatenate these parts, unpack them in order with /bin/sh        
  16. #
  17. #    Run the following text with /bin/sh to create:
  18. #      README
  19. #      INSTALL
  20. #      calc.el
  21. #      calc-ext.el
  22. #      calc.texinfo
  23. #
  24. if test -r s2_seq_.tmp
  25. then echo "Must unpack archives in sequence!"
  26.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  27.      exit 1; fi
  28. echo "x - extracting README (Text)"
  29. sed 's/^X//' << 'SHAR_EOF' > README &&
  30. X
  31. XThis tar file contains version 1.01 of Calc, an advanced desk
  32. Xcalculator for GNU Emacs.
  33. X
  34. X"Calc"  Copyright 1990  Dave Gillespie
  35. X                        256-80 Caltech
  36. X                        Pasadena CA 91125
  37. X                        daveg@csvax.caltech.edu, cit-vax!daveg
  38. X
  39. X
  40. X
  41. XFrom the Introduction to the manual:
  42. X
  43. X  "Calc" is an advanced calculator and mathematical tool that runs as
  44. X  part of the GNU Emacs environment.  Very roughly based on the HP-28/48
  45. X  series of calculators, its many features include:
  46. X
  47. X    * Choice of algebraic or RPN style entry of calculations.
  48. X    * Arbitrary precision integers and floating-point numbers.
  49. X    * Arithmetic on rational numbers, complex numbers (rectangular and polar),
  50. X      error forms with standard deviations, open and closed intervals, vectors
  51. X      and matrices, quantities with units, and simple algebraic expressions.
  52. X    * Mathematical operations such as logarithms and trig functions.
  53. X    * Programmer's features (bitwise operations, non-decimal integers).
  54. X    * Number theoretical features such as prime factorization and arithmetic
  55. X      modulo M for any M.
  56. X    * Algebraic manipulation features, including symbolic calculus.
  57. X    * Kill and yank to and from regular editing buffers.
  58. X    * Easy programming using keyboard macros, algebraic formulas,
  59. X      algebraic rewrite rules, or Lisp code.
  60. X
  61. X
  62. X
  63. XTo install Calc:
  64. X
  65. X  1. Create a directory for Calc
  66. X  2. "cd" to that directory
  67. X  3. Place calc-1.01.tar.Z in the directory (be sure to ftp it in binary mode)
  68. X  4. Type "uncompress calc-1.01.tar.Z"
  69. X  5. Type "tar xvf calc-1.01.tar"
  70. X4,5. Alternatively: "zcat calc1.01.tar.Z | tar xvf -"
  71. X  6. Follow the instructions in the file "INSTALL".
  72. X
  73. X
  74. X
  75. XThe files contained in this tar file are:
  76. X
  77. X  README        This very file.
  78. X
  79. X  INSTALL        Installation instructions (excerpted from the manual).
  80. X
  81. X  calc.el        The main source file.  This contains just the basic
  82. X            arithmetic functions, and is kept small for fast
  83. X            loading.  124K.
  84. X
  85. X  calc-ext.el        The rest of the Calculator source.  This file is
  86. X            auto-loaded the first time you use an advanced Calc
  87. X            command.  460K.
  88. X
  89. X  calc.elc        The byte-compiled version of Calc.  You can make
  90. X  calc-ext.elc        these yourself from calc.el and calc-ext.el if you
  91. X            prefer; use the M-x byte-compile-file command.
  92. X            (Not available in shar distribution; 82K + 358K.)
  93. X
  94. X  calc.texinfo      Documentation for Calc.  This can be turned into
  95. X            a printed manual and also into on-line help.  465K.
  96. X            Beware: printed, this is over 200 pages!
  97. X
  98. X  macedit.el        A handy utility for editing keyboard macros; good
  99. X            for using Calc as a programmable calculator.  19K.
  100. X
  101. X
  102. XCalc is written entirely in Emacs Lisp, for maximum portability.
  103. XYou do not need to recompile Emacs to install and use Calc.
  104. X
  105. XYou will need about two megabytes of disk space to hold Calc with
  106. Xits Info documentation.
  107. X
  108. XSee the file INSTALL for installation instructions.  If you're impatient,
  109. Xuse `M-x load-file' to load `calc.elc' and `calc-ext.elc', then type
  110. X`M-x calc' to run the Calculator.  Type `?' for help; read `calc.texinfo'
  111. Xfor the complete documentation.
  112. X
  113. XDon't even try to run Calc in uncompiled (.el) form!  It's far too slow.
  114. X
  115. X
  116. XI am anxious to hear about your experiences using Calc.  Send mail to
  117. X"daveg@csvax.caltech.edu", or "cit-vax!daveg".  A bug report is most
  118. Xuseful if you include the exact input and output that occurred, any
  119. Xmodes in effect (such as the current precision), and so on.  If you
  120. Xfind Calc is difficult to operate in any way, or if you have other
  121. Xsuggestions, don't hesitate to let me know.  If you find errors
  122. X(including simple typos) in the manual, let me know.  Even if you find
  123. Xno bugs at all I would love to hear your opinions.
  124. X
  125. XThe latest Calc tar files and patches are available for anonymous FTP
  126. Xon csvax.caltech.edu.  Look in the "pub" subdirectory.
  127. X
  128. XThanks,
  129. X
  130. X                                -- Dave
  131. X
  132. X
  133. X
  134. X
  135. X
  136. XSummary of changes to "Calc"
  137. X------- -- ------- --  ----
  138. X
  139. X
  140. XVersion 1.01:
  141. X
  142. X * Added a tutorial section to the manual.
  143. X
  144. X * Next and Prev for node Strings in the manual were reversed; fixed.
  145. X
  146. X * Changed "'bignum" in calc-isqrt-bignum-iter to "'bigpos".
  147. X
  148. X * Fixed a bug that prevented "$" from working during algebraic entry.
  149. X
  150. X * Fixed a bug caused by an X (last-X) command following a K (macro) command.
  151. X
  152. X * Fixed a bug in which K command incorrectly formatted stack in Big mode.
  153. X
  154. X * Added space between unary operators and non-flat compositions.
  155. X   (Otherwise, "-(a/b)" in Big mode blended the minus sign into the rule!)
  156. X
  157. X * Fixed formatting of (-1)^n in Big mode.
  158. X
  159. X * Fixed some problems relating to "not" operator in Pascal language mode.
  160. X
  161. X * Fixed several bugs relating to V M ' and V M $ sequences.
  162. X
  163. X * Fixed matrix-vector multiplication to produce a vector.
  164. X
  165. X * Introduced Z ` ... Z ' commands; renamed old Z ' to Z #.
  166. X
  167. X * Fixed various other bugs.
  168. X
  169. X * Added calc-settings-file variable suggested by C. Witty.
  170. X
  171. XVersion 1.00:
  172. X
  173. X * First official release of Calc.
  174. X
  175. X * If you used the Beta test version (0.01), you will find that this
  176. X   version of Calc is over 50% larger than the original release.
  177. X   General areas of improvement include much better algebra features;
  178. X   operations on units; language modes; simplification modes; interval
  179. X   arithmetic; vector mapping and reduction.  Other new commands include
  180. X   calc-fraction and calc-grab-region.  The program has been split into
  181. X   two parts for faster loading, and the manual is more complete.
  182. X
  183. SHAR_EOF
  184. chmod 0664 README || echo "restore of README fails"
  185. set `wc -c README`;Sum=$1
  186. if test "$Sum" != "5418"
  187. then echo original size 5418, current size $Sum;fi
  188. echo "x - extracting INSTALL (Text)"
  189. sed 's/^X//' << 'SHAR_EOF' > INSTALL &&
  190. X
  191. XInstallation
  192. X************
  193. X
  194. XCalc comes as a pair of Emacs Lisp files, generally called `calc.el' and
  195. X`calc-ext.el'.  The first contains the basic foundations of the
  196. XCalculator, and is as small as possible to promote quick loading.  The
  197. Xsecond contains all the more advanced commands and functions.  Calc is
  198. Xusually installed so that the `M-x calc' or `M-#' command auto-loads
  199. Xonly the first part, and the second part is auto-loaded whenever the
  200. Xfirst advanced feature is used.
  201. X
  202. XCalc is written in a way that maximizes performance when its code has been
  203. Xbyte-compiled; a side effect is that performance is seriously degraded if
  204. Xit *isn't* compiled.  Thus, it is essential to compile the Calculator
  205. Xbefore trying to use it.  The Emacs command `M-x byte-compile-file'
  206. Xis used to compile an Emacs Lisp file.  Compile each of `calc.el' and
  207. X`calc-ext.el' to obtain byte-code files `calc.elc' and
  208. X`calc-ext.elc'.  You may find you need to do `M-x load-file
  209. Xcalc.elc' before compiling `calc-ext.el' will work.
  210. X
  211. XFor your convenience, the FTP distribution of Calc, obtainable from
  212. Xanonymous FTP on `csvax.caltech.edu', includes already-compiled
  213. Xversions of both of these files.
  214. X
  215. XTo teach Emacs how to load in Calc when you type `M-x calc' for the
  216. Xfirst time, include these lines in your `.emacs' file (if you are
  217. Xinstalling Calc just for your own use), or the system's `lisp/default'
  218. Xfile (if you are installing Calc publicly).
  219. X
  220. X     (autoload 'calc             ".../calc.elc"     "Calculator Mode" t nil)
  221. X     (autoload 'calc-extensions  ".../calc-ext.elc" nil nil nil)
  222. X     (autoload 'quick-calc       ".../calc.elc"     "Quick Calculator" t nil)
  223. X     (autoload 'calc-grab-region ".../calc-ext.elc" nil t nil)
  224. X     (autoload 'defmath          ".../calc-ext.elc" nil t t)
  225. X
  226. Xwhere `.../calc.elc' represents the full path to the `calc.elc'
  227. Xfile, and similarly for `.../calc-ext.elc'.  If you have installed
  228. Xthese files in Emacs' main `lisp/' directory, you can just write
  229. X`"calc.elc"' and `"calc-ext.elc"'.
  230. X
  231. XThe `autoload' command for `calc' is what loads `calc.elc'
  232. Xwhen you type `M-x calc'.  The `autoload' for `calc-extensions'
  233. Xbrings in the extensions module; Calc takes care to call the
  234. X`calc-extensions' function (which doesn't actually do anything)
  235. Xbefore any operation that requires the extensions to be present.
  236. XThe other three `autoload' commands are for functions which might
  237. Xreasonably be used before the user has typed `M-x calc' for the
  238. Xfirst time.
  239. X
  240. XIf you don't want to bother with a split Calculator, you can simply
  241. Xconcatenate `calc-ext.elc' onto the end of `calc.elc', rewrite
  242. Xthe above `autoload' commands all to point to the combined file,
  243. Xand treat Calc as one big program.  You may need to do this if
  244. X`autoload' is giving you problems.
  245. X
  246. XYou may also wish to bind the `calc' command to a key.  The
  247. Xrecommended keystroke is `M-#' (i.e., Meta-Shift-3).  To set up
  248. Xthis key binding, include this command in your `.emacs' or
  249. X`lisp/default' file:
  250. X
  251. X     (global-set-key "\e#" 'calc)
  252. X
  253. XThere are no standard key assignments for `quick-calc' and
  254. X`calc-grab-region', but you may wish to define some.
  255. X
  256. XThe file `macedit.el' contains another useful Emacs extension
  257. Xcalled `edit-kbd-macro'.  It allows you to edit a keyboard macro
  258. Xin human-readable form.  The `Z E' command in Calc knows how to
  259. Xuse it to edit user commands that have been defined by keyboard macros.
  260. XTo autoload it, you will want to include the commands,
  261. X
  262. X     (autoload 'edit-kbd-macro      ".../macedit.elc" "Edit Keyboard Macro" t nil)
  263. X     (autoload 'edit-last-kbd-macro ".../macedit.elc" "Edit Keyboard Macro" t nil)
  264. X
  265. XThe documentation for Calc (i.e., this manual) comes in a file
  266. X`calc.texinfo'.  To format this for use as an on-line manual,
  267. Xopen this file for editing in Emacs and give the command
  268. X`M-x texinfo-format-buffer'.  When this finishes, type `C-x C-s'
  269. Xto save.  The result will be a collection of files whose names begin
  270. Xwith `calc-info'.  You can also format this into a printable
  271. Xdocument using TeX, but beware, the manual is about 170 printed pages!
  272. X
  273. XThere is a Lisp variable called `calc-info-filename' which holds
  274. Xthe name of the Info file containing Calc's on-line documentation.
  275. XIts default value is `calc-info', which will work correctly if
  276. Xthe Info files are stored in Emacs' main `info/' directory.  If
  277. Xyou keep them elsewhere, you will want to put a command of the form,
  278. X
  279. X     (setq calc-info-filename ".../calc-info")
  280. X
  281. Xin your `.emacs' or `lisp/default' file, where again `...'
  282. Xrepresents the directory containing the Info files.
  283. X
  284. XAnother variable you might want to set is `calc-settings-file', which
  285. Xholds the file name in which commands like `m m' and `Z P' store
  286. X"permanent" definitions.  The default value for this variable is
  287. X`"~/.emacs"'.  If `calc-settings-file' does not contain `".emacs"' as a
  288. Xsubstring, and if the variable `calc-loaded-settings-file' is `nil',
  289. Xthen Calc will automatically load your settings file (if it exists) the
  290. Xfirst time Calc is invoked.
  291. X
  292. XTo test your installation of Calc, start a fresh Emacs and type `M-#'
  293. Xto make sure the autoload commands and key bindings work.  Now, type
  294. X`i' to make sure Calc can find its Info documentation.  Press `q'
  295. Xto exit the Info system.  Type `20 S' to compute the sine of
  296. X20 degrees; this will test the autoloading of the extensions module.
  297. XThe result should be 0.342020143326.  Finally, press `M-#' again to
  298. Xmake sure the Calculator can exit.
  299. X
  300. X(The above text is included in both the Calc documentation and the
  301. Xfile INSTALL in the Calc distribution directory.)
  302. SHAR_EOF
  303. chmod 0644 INSTALL || echo "restore of INSTALL fails"
  304. set `wc -c INSTALL`;Sum=$1
  305. if test "$Sum" != "5522"
  306. then echo original size 5522, current size $Sum;fi
  307. echo "x - extracting calc.el (Text)"
  308. sed 's/^X//' << 'SHAR_EOF' > calc.el &&
  309. X;; Calculator for GNU Emacs
  310. X;; Copyright (C) 1990 Dave Gillespie
  311. X
  312. X;; This file is part of GNU Emacs.
  313. X
  314. X;; GNU Emacs is distributed in the hope that it will be useful,
  315. X;; but WITHOUT ANY WARRANTY.  No author or distributor
  316. X;; accepts responsibility to anyone for the consequences of using it
  317. X;; or for whether it serves any particular purpose or works at all,
  318. X;; unless he says so in writing.  Refer to the GNU Emacs General Public
  319. X;; License for full details.
  320. X
  321. X;; Everyone is granted permission to copy, modify and redistribute
  322. X;; GNU Emacs, but only under the conditions described in the
  323. X;; GNU Emacs General Public License.   A copy of this license is
  324. X;; supposed to have been given to you along with GNU Emacs so you
  325. X;; can know your rights and responsibilities.  It should be in a
  326. X;; file named COPYING.  Among other things, the copyright notice
  327. X;; and this notice must be preserved on all copies.
  328. X
  329. X
  330. X;;; This is part I of the Emacs Calculator.  It defines simple arithmetic
  331. X;;; commands only.  Assuming the autoload commands shown below have been
  332. X;;; done, the Calculator will autoload the remaining commands from calc-ext.elc
  333. X;;; whenever one is first needed.  If you wish, you can concatenate calc-ext
  334. X;;; onto the end of calc (.el or .elc) to make one big file.
  335. X
  336. X;;; Suggested usage:
  337. X;;;
  338. X;;;   (autoload 'calc ".../calc.elc" "Calculator Mode" t nil)
  339. X;;;   (autoload 'quick-calc ".../calc.elc" "Quick Calculator" t nil)
  340. X;;;   (autoload 'calc-grab-region ".../calc-ext.elc" nil t nil)
  341. X;;;   (autoload 'defmath ".../calc-ext.elc" nil t t)
  342. X;;;   (autoload 'calc-extensions ".../calc-ext.elc" nil nil nil)
  343. X;;;   (global-set-key "\e#" 'calc)
  344. X;;;   M-x calc
  345. X;;;
  346. X;;; where ".../calc.elc" represents the full path for "calc.elc",
  347. X;;; and ".../calc-ext.elc" is the path of the companion file containing
  348. X;;; all of the more advanced Calc commands.
  349. X
  350. X
  351. X;;; Author's address:
  352. X;;;   Dave Gillespie, 256-80 Caltech, Pasadena CA 91125.
  353. X;;;   daveg@csvax.caltech.edu, ...!cit-vax!daveg.
  354. X;;;
  355. X;;; This file and the manual, calc.texinfo, are available from anonymous FTP
  356. X;;; on csvax.caltech.edu [192.12.18.1]; look in ~ftp/pub/calc.
  357. X;;;
  358. X;;; Bug reports and suggestions are always welcome!
  359. X
  360. X
  361. X;;; All functions, macros, and Lisp variables defined here begin with one
  362. X;;; of the prefixes "math", "Math", or "calc", with the exception of
  363. X;;; "another-calc".  User-accessible variables begin with "var-".
  364. X
  365. X
  366. X
  367. X(provide 'calc)
  368. X
  369. X(defmacro calc-record-compilation-date-macro ()
  370. X  (` (setq calc-version (concat "Emacs Calc Mode"
  371. X                " v1.01 by Dave Gillespie"
  372. X                ", installed "
  373. X                (, (current-time-string))
  374. X                " by "
  375. X                (, (user-full-name)))))
  376. X)
  377. X(defun calc-record-compilation-date ()
  378. X  (calc-record-compilation-date-macro)
  379. X)
  380. X(calc-record-compilation-date)
  381. X
  382. X
  383. X(defvar calc-info-filename "calc-info"
  384. X  "*File name in which to look for the Calculator's Info documentation.")
  385. X
  386. X
  387. X(defvar calc-extensions-loaded nil)
  388. X
  389. X
  390. X
  391. X;;; IDEAS:
  392. X;;;
  393. X;;;   Consider breaking calc-ext.el into several extension modules:
  394. X;;;      Base extensions, algebra/units, scientific, programming
  395. X;;;
  396. X;;;   How about putting cursor on an operator or functor in stack window
  397. X;;;      to indicate the subterm to which a command should apply?
  398. X;;;   Make math-simplify faster!
  399. X;;;   Provide analogues of Mathematica's polynomial-munching ops:
  400. X;;;      Together, Apart, Cancel, Factor, GCD, quotient/remainder.
  401. X;;;   Automatically generate derivatives for functions defined with Z F.
  402. X;;;   Handle commutativity and associativity among +, -, *, / in rewrite rules.
  403. X;;;
  404. X;;;   In no-simplify mode, have a key which executes the top-level call
  405. X;;;      once, but does not execute any of the arguments' calls.
  406. X;;;   Put a set of evaluations in the c-prefix menu, analogous to m-prefix.
  407. X;;;
  408. X;;;   During algebraic entry, hit ` to switch to calc-edit entry.
  409. X;;;
  410. X;;;   When the stack is truncated, put the "." on the *second*-to-bottom line.
  411. X;;;   When formatting formulas, suppress extra spaces inside vectors!
  412. X;;;   Implement line-breaking in non-flat compositions.
  413. X;;;   Implement structured line-breaking using level information.
  414. X;;;   Implement matrix formatting with multi-line components.
  415. X;;;
  416. X;;;   Support lambda notation in Z F and Z G commands.
  417. X;;;   Have "Z R" define a user command based on a set of rewrite rules.
  418. X;;;   Support "incf" and "decf" in defmath definitions.
  419. X;;;   Have defmath generate calls to calc-binary-op or calc-unary-op.
  420. X;;;
  421. X;;;   Allow calc-word-size=0 => Common Lisp-style signed bitwise arithmetic.
  422. X;;;   Consider implementing some other special functions.
  423. X;;;   May as well make continued-fractions stuff available to the user.
  424. X;;;   Provide date arithmetic a la HP 48.
  425. X;;;
  426. X;;;   Implement some more built-in statistical functions:
  427. X;;;      mean, median, variance, std dev of a list.
  428. X;;;   How about fitting a list or Nx2 matrix to a line or curve.
  429. X;;;
  430. X;;;   How about matrix eigenvalues, SVD, pseudo-inverse, etc.?
  431. X;;;   Should cache matrix inverses as well as decompositions.
  432. X;;;   Allow calc-edit to edit a matrix in a more convenient form.
  433. X;;;
  434. X;;;   Replace hokey formulas for complex functions with formulas designed
  435. X;;;      to minimize roundoff while maintaining the proper branch cuts.
  436. X;;;   Provide a better implementation for math-sin-cos-raw.
  437. X;;;   Provide a better implementation for math-hypot.
  438. X;;;   Provide a better implementation for math-make-frac.
  439. X;;;   Provide a better implementation for math-prime-factors.
  440. X;;;   Provide a better implementation for math-integral.
  441. X;;;   Clean up some of the definitions in the units table.
  442. X;;;   Implement dfact for large inputs using gamma function.
  443. X;;;
  444. X;;;   Provide more examples in the tutorial section of the manual.
  445. X;;;   Cover in the tutorial:  language modes, simplification modes,
  446. X;;;       bitwise stuff, rewrite rules.
  447. X;;;   Provide more Lisp programming examples in the manual.
  448. X;;;   Finish the Internals section of the manual.
  449. X;;;
  450. X;;;   Tim suggests adding spreadsheet-like features.
  451. X;;;   How about ultra-low-resolution plots?  (Probably too slow.)
  452. X;;;   Implement language modes for Lisp, Ada, ...?
  453. X;;;
  454. X
  455. X
  456. X;;; Graphically manipulating a composed expression:
  457. X;;;   Have an option in math-compose-expr which wraps each term with a
  458. X;;;   "(tag C X)" form where C is the composition term and X is the
  459. X;;;   sub-expression that generated it.  Now, call a variant of
  460. X;;;   math-simplify-comp which returns the innermost X whose C contained
  461. X;;;   a given (x,y) location.  In addition, have a variant of
  462. X;;;   math-simplify-comp which replaces every non-blank character inside
  463. X;;;   a tag form for a given X with some highlight character like "#".
  464. X;;;   (Consider supporting Epoch's true highlighting here.)
  465. X
  466. X;;; Idea: Have "{" and "}" mean select next larger or smaller sub-formula
  467. X;;;   around the cursor; when a sub-formula is selected, the next command
  468. X;;;   (of any sort) applies to that sub-formula.  Have calc-top-n and
  469. X;;;   calc-enter-result fake this up.  Print a warning if a stack entry is
  470. X;;;   highlighted which is not touched by the next command.
  471. X
  472. X
  473. X;;; For atan series, if x > tan(pi/12) (about 0.268) reduce using the identity
  474. X;;;   atan(x) = atan((x * sqrt(3) - 1) / (sqrt(3) + x)) + pi/6.
  475. X
  476. X
  477. X;;; A better integration algorithm:
  478. X;;;   Use breadth-first instead of depth-first search, as follows:
  479. X;;;    The integral cache allows unfinished integrals in symbolic notation
  480. X;;;    on the righthand side.  An entry with no unfinished integrals on the
  481. X;;;    RHS is "complete"; references to it elsewhere are replaced by the
  482. X;;;    integrated value.  More than one cache entry for the same integral
  483. X;;;    may exist, though if one becomes complete, the others may be deleted.
  484. X;;;    The integrator works by using every applicable rule (such as
  485. X;;;    substitution, parts, linearity, etc.) to generate possible righthand
  486. X;;;    sides, all of which are entered into the cache.  Now, as long as the
  487. X;;;    target integral is not complete (and the time limit has not run out)
  488. X;;;    choose an incomplete integral from the cache and, for every integral
  489. X;;;    appearing in its RHS's, add those integrals to the cache using the
  490. X;;;    same substitition, parts, etc. rules.  The cache should be organized
  491. X;;;    as a priority queue, choosing the "simplest" incomplete integral at
  492. X;;;    each step, or choosing randomly among equally simple integrals.
  493. X;;;    Simplicity equals small size, and few steps removed from the original
  494. X;;;    target integral.  Note that when the integrator finishes, incomplete
  495. X;;;    integrals can be left in the cache, so the algorithm can start where
  496. X;;;    it left off if another similar integral is later requested.
  497. X;;;   Breadth-first search would avoid the nagging problem of, e.g., whether
  498. X;;;   to use parts or substitution first, and which decomposition is best.
  499. X;;;   All are tried, and any path that diverges will quickly be put on the
  500. X;;;   back burner by the priority queue.
  501. X;;;   Note: Probably a good idea to call math-simplify-extended before
  502. X;;;   measuring a formula's simplicity.
  503. X
  504. X
  505. X
  506. X
  507. X
  508. X
  509. X;;; NOTE: The default values listed below and those defined in
  510. X;;;       calc-mode-vars-list must match.
  511. X
  512. X(defvar calc-mode-map nil "Keymap for calc-mode.")
  513. X(defvar calc-digit-map nil "Keymap for digit entry in calc-mode.")
  514. X
  515. X(defvar calc-trail-pointer nil "\"Current\" entry in trail buffer.")
  516. X
  517. X(defvar calc-stack '((top-of-stack 1)) "Calculator stack.")
  518. X(defvar calc-undo-list nil "List of previous operations in calc-mode.")
  519. X(defvar calc-redo-list nil "List of recent undo operations in calc-mode.")
  520. X(defvar calc-main-buffer nil "The Calculator buffer.")
  521. X(defvar calc-why nil "Explanations of most recent errors.")
  522. X(defvar calc-next-why nil)
  523. X
  524. X(defvar calc-last-kill nil "Last number killed in calc-mode.")
  525. X(defvar calc-previous-alg-entry nil "Previous string entered with algebraic entry.")
  526. X(defvar calc-dollar-values nil "Values to be used for '$' in expressions.")
  527. X(defvar calc-dollar-used nil "Highest order of '$' that occur in expression.")
  528. X(defvar calc-quick-prev-results nil "Previous results from Quick Calc.")
  529. X
  530. X(defvar calc-always-load-extensions nil
  531. X  "*If non-NIL, load the calc-ext module automatically when calc is loaded.")
  532. X
  533. X(defvar calc-stack-top 1
  534. X  "Index into calc-stack of \"top\" of stack.
  535. XThis is 1 unless calc-truncate-stack has been used.")
  536. X
  537. X(defvar calc-line-numbering t
  538. X  "*If non-NIL, display line numbers in Calculator stack.")
  539. X
  540. X(defvar calc-line-breaking t
  541. X  "*If non-NIL, break long values across multiple lines in Calculator stack.")
  542. X
  543. X(defvar calc-display-just nil
  544. X  "*If NIL, stack display is left-justified.
  545. XIf 'right, stack display is right-justified.
  546. XIf 'center, stack display is centered."
  547. X)
  548. X
  549. X(defvar calc-number-radix 10
  550. X  "*Radix for entry and display of numbers in calc-mode, 2-36.")
  551. X
  552. X(defvar calc-leading-zeros nil
  553. X  "*If non-NIL, leading zeros are provided to pad integers to calc-word-size.")
  554. X
  555. X(defvar calc-group-digits nil
  556. X  "*If non-NIL, group digits in large displayed integers by inserting spaces.
  557. XIf an integer, group that many digits at a time.
  558. XIf 't', use 4 for binary and hex, 3 otherwise.")
  559. X
  560. X(defvar calc-group-char ","
  561. X  "*The character (in the form of a string) to be used for grouping digits.
  562. XThis is used only when calc-group-digits mode is on.")
  563. X
  564. X(defvar calc-point-char "."
  565. X  "*The character (in the form of a string) to be used as a decimal point.")
  566. X
  567. X(defvar calc-frac-format ":"
  568. X  "*Format of displayed fractions; a string of one or two of \":\" or \"/\".")
  569. X
  570. X(defvar calc-prefer-frac nil
  571. X  "*If non-NIL, prefer fractional over floating-point results.")
  572. X
  573. X(defvar calc-hms-format "%s@ %s' %s\""
  574. X  "*Format of display hours-minutes-seconds angles, a format string.
  575. XString must contain three %s marks, for hours, minutes, seconds respectively.")
  576. X
  577. X(defvar calc-float-format '(float 0)
  578. X  "*Format to use for display of floating-point numbers in calc-mode.
  579. XMust be a list of one of the following forms:
  580. X   (float 0)      Floating point format, display full precision.
  581. X   (float N)      N > 0: Floating point format, at most N significant figures.
  582. X   (float -N)     -N < 0: Floating point format, calc-internal-prec - N figs.
  583. X   (fix N)        N >= 0: Fixed point format, N places after decimal point.
  584. X   (sci 0)        Scientific notation, full precision.
  585. X   (sci N)        N > 0: Scientific notation, N significant figures.
  586. X   (sci -N)       -N < 0: Scientific notation, calc-internal-prec - N figs.
  587. X   (eng 0)        Engineering notation, full precision.
  588. X   (eng N)        N > 0: Engineering notation, N significant figures.
  589. X   (eng -N)       -N < 0: Engineering notation, calc-internal-prec - N figs.")
  590. X
  591. X(defvar calc-full-float-format '(float 0)
  592. X  "*Format to use when full precision must be displayed.")
  593. X
  594. X(defvar calc-complex-format nil
  595. X  "*Format to use for display of complex numbers in calc-mode.  Must be one of:
  596. X   nil            Use (x, y) form.
  597. X   i              Use x + yi form.
  598. X   j              Use x + yj form.")
  599. X
  600. X(defvar calc-complex-mode 'cplx
  601. X  "*Preferred form, either 'cplx or 'polar, for complex numbers.")
  602. X
  603. X(defvar calc-display-strings nil
  604. X  "*If non-NIL, display vectors of byte-sized integers as strings.")
  605. X
  606. X(defvar calc-matrix-just 'center
  607. X  "*If NIL, vector elements are left-justified.
  608. XIf 'right, vector elements are right-justified.
  609. XIf 'center, vector elements are centered."
  610. X)
  611. X
  612. X(defvar calc-vector-commas ","
  613. X  "*If non-NIL, separate elements of displayed vectors with this string.")
  614. X
  615. X(defvar calc-vector-brackets "[]"
  616. X  "*If non-NIL, surround displayed vectors with these characters.")
  617. X
  618. X(defvar calc-function-open "("
  619. X  "*Open-parenthesis string for function call notation.")
  620. X
  621. X(defvar calc-function-close ")"
  622. X  "*Close-parenthesis string for function call notation.")
  623. X
  624. X(defvar calc-language nil
  625. X  "*Language or format for entry and display of stack values.  Must be one of:
  626. X   nil            Use standard Calc notation.
  627. X   flat           Use standard Calc notation, one-line format.
  628. X   big               Display formulas in 2-d notation (enter w/standard notation).
  629. X   unform      Use unformatted display: add(a, mul(b,c)).
  630. X   c              Use C language notation.
  631. X   pascal         Use Pascal language notation.
  632. X   fortran        Use Fortran language notation.
  633. X   tex            Use TeX notation.
  634. X   math           Use Mathematica(tm) notation.")
  635. X
  636. X(defvar calc-language-option nil
  637. X  "*Numeric prefix argument for the command that set calc-language.")
  638. X
  639. X(defvar calc-language-output-filter nil
  640. X  "Function through which to pass strings after formatting.")
  641. X
  642. X(defvar calc-language-input-filter nil
  643. X  "Function through which to pass strings before parsing.")
  644. X
  645. X(defvar calc-radix-formatter nil
  646. X  "*Formatting function used for non-decimal integers.")
  647. X
  648. X(defvar calc-word-size 32
  649. X  "*Minimum number of bits per word, if any, for binary operations in calc-mode.")
  650. X
  651. X(defvar calc-previous-modulo nil
  652. X  "*Most recently used value of M in a modulo form.")
  653. X
  654. X(defvar calc-simplify-mode nil
  655. X  "*Type of simplification applied to results.
  656. XIf 'none, results are not simplified when pushed on the stack.
  657. XIf 'num, functions are simplified only when args are constant.
  658. XIf NIL, only fast simplifications are applied.
  659. XIf 'binary, math-clip is applied if appropriate.
  660. XIf 'alg, math-simplify is applied.
  661. XIf 'ext, math-simplify-extended is applied.
  662. XIf 'units, math-simplify-units is applied.")
  663. X
  664. X(defvar calc-mapping-dir nil
  665. X  "*Last direction specified in a Map or Reduce command.")
  666. X
  667. X(defvar calc-display-raw nil
  668. X  "*If non-NIL, calculator display shows unformatted Lisp exprs.  (For debugging)")
  669. X
  670. X(defvar calc-display-sci-high 0
  671. X  "*Floating-point numbers with this positive exponent or higher above the
  672. Xcurrent precision are displayed in scientific notation in calc-mode.")
  673. X
  674. X(defvar calc-display-sci-low -3
  675. X  "*Floating-point numbers with this negative exponent or lower are displayed
  676. Xscientific notation in calc-mode.")
  677. X
  678. X(defvar calc-internal-prec 12
  679. X  "*Number of digits of internal precision for calc-mode calculations.")
  680. X
  681. X(defvar calc-inverse-flag nil
  682. X  "*If non-NIL, next operation is Inverse.")
  683. X
  684. X(defvar calc-hyperbolic-flag nil
  685. X  "*If non-NIL, next operation is Hyperbolic.")
  686. X
  687. X(defvar calc-angle-mode 'deg
  688. X  "*If deg, angles are in degrees; if rad, angles are in radians.
  689. XIf hms, angles are in degrees-minutes-seconds.")
  690. X
  691. X(defvar calc-algebraic-mode nil
  692. X  "*If non-NIL, numeric entry accepts whole algebraic expressions.
  693. XIf NIL, algebraic expressions must be preceded by \"'\".")
  694. X
  695. X(defvar calc-symbolic-mode nil
  696. X  "*If non-NIL, inexact numeric computations like sqrt(2) are postponed.
  697. XIf NIL, computations on numbers always yield numbers where possible.")
  698. X
  699. X(defvar calc-integral-limit 3
  700. X  "*An integer which governs how long calc-integral will look for an integral.
  701. XThe integrator often uses substitution or integration by parts to transform
  702. Xan integral into another one; this controls how many levels of nested
  703. Xsub-integrations are allowed before a given path is abandoned.")
  704. X
  705. X(defvar calc-window-height 7
  706. X  "*Initial height of Calculator window.")
  707. X
  708. X(defvar calc-display-trail t
  709. X  "*If non-NIL, M-x calc creates a window to display Calculator trail.")
  710. X
  711. X(defvar calc-display-working-message 'lots
  712. X  "*If non-NIL, display \"Working...\" for potentially slow Calculator commands.")
  713. X
  714. X(defvar calc-auto-why nil
  715. X  "*If non-NIL, automatically execute a \"why\" command to explain odd results.")
  716. X
  717. X(defvar calc-said-hello nil)
  718. X(defvar calc-executing-macro nil)
  719. X
  720. X
  721. X(defvar calc-other-modes nil
  722. X  "List of used-defined strings to append to Calculator mode line.")
  723. X
  724. X
  725. X(defvar calc-settings-file "~/.emacs"
  726. X  "*File in which to record permanent settings; default is \"~/.emacs\".")
  727. X
  728. X(defvar calc-loaded-settings-file nil)
  729. X
  730. X
  731. X(defvar calc-bug-address "daveg@csvax.caltech.edu"
  732. X  "*Address of the author of Calc, for use by report-calc-bug.")
  733. X
  734. X
  735. X(defvar var-i '(special-const (math-imaginary 1))
  736. X  "*Calculator variable representing the imaginary constant 'i'.")
  737. X
  738. X(defvar var-pi '(special-const (math-pi))
  739. X  "*Calculator variable representing the constant 'pi'.")
  740. X
  741. X(defvar var-e '(special-const (math-e))
  742. X  "*Calculator variable representing the constant 'e'.")
  743. X
  744. X
  745. X
  746. X;;; Set up the standard keystroke (M-#) to run the Calculator, if that key
  747. X;;; has not yet been bound to anything.  For best results, the user should
  748. X;;; do this before Calc is even loaded, so that M-# can auto-load Calc.
  749. X(or (global-key-binding "\e#")
  750. X    (global-set-key "\e#" 'calc))
  751. X
  752. X
  753. X(defun calc-define-del (map func)
  754. X  (define-key map "\C-d" func)
  755. X  (mapcar (function (lambda (x) (define-key map x func)))
  756. X      (append (where-is-internal 'delete-backward-char global-map)
  757. X          (where-is-internal 'backward-delete-char global-map)))
  758. X)
  759. X
  760. X;; Still unused: f g j O W Y { }
  761. X(if calc-mode-map
  762. X    nil
  763. X  (setq calc-mode-map (make-keymap))
  764. X  (suppress-keymap calc-mode-map t)
  765. X  (define-key calc-mode-map "+" 'calc-plus)
  766. X  (define-key calc-mode-map "-" 'calc-minus)
  767. X  (define-key calc-mode-map "*" 'calc-times)
  768. X  (define-key calc-mode-map "/" 'calc-divide)
  769. X  (define-key calc-mode-map "%" 'calc-mod)
  770. X  (define-key calc-mode-map "&" 'calc-inv)
  771. X  (define-key calc-mode-map "^" 'calc-power)
  772. X  (define-key calc-mode-map "e" 'calcDigit-start)
  773. X  (define-key calc-mode-map "h" 'describe-mode)
  774. X  (define-key calc-mode-map "i" 'calc-info)
  775. X  (define-key calc-mode-map "n" 'calc-change-sign)
  776. X  (define-key calc-mode-map "o" 'calc-realign)
  777. X  (define-key calc-mode-map "p" 'calc-precision)
  778. X  (define-key calc-mode-map "q" 'calc-quit)
  779. X  (define-key calc-mode-map "w" 'calc-why)
  780. X  (define-key calc-mode-map "?" 'calc-help)
  781. X  (define-key calc-mode-map " " 'calc-enter)
  782. X  (define-key calc-mode-map "<" 'calc-scroll-left)
  783. X  (define-key calc-mode-map ">" 'calc-scroll-right)
  784. X  (define-key calc-mode-map "'" 'calc-algebraic-entry)
  785. X  (define-key calc-mode-map "$" 'calc-auto-alg-entry)
  786. X  (define-key calc-mode-map "\"" 'calc-auto-alg-entry)
  787. X  (define-key calc-mode-map "\t" 'calc-roll-down)
  788. X  (define-key calc-mode-map "\M-\t" 'calc-roll-up)
  789. X  (define-key calc-mode-map "\C-m" 'calc-enter)
  790. X  (define-key calc-mode-map "\C-j" 'calc-over)
  791. X  (calc-define-del calc-mode-map 'calc-pop)
  792. X  (mapcar (function
  793. X       (lambda (x)
  794. X         (define-key calc-mode-map (char-to-string x) 'undefined)))
  795. X      "fgjOWY{}")
  796. X  (mapcar (function
  797. X       (lambda (x)
  798. X         (define-key calc-mode-map (char-to-string x) 'calc-missing-key)))
  799. X      (concat "ABCDEFGHIJKLMNPQRSTUVXZabcdklmrstuvxyz"
  800. X          ":\\|!()[],;=~`\C-k\M-k\C-w\M-w\C-y\C-_"))
  801. X  (mapcar (function
  802. X       (lambda (x)
  803. X         (define-key calc-mode-map (char-to-string x) 'calcDigit-start)))
  804. X      "_0123456789.#@")
  805. X)
  806. X
  807. X(if calc-digit-map
  808. X    nil
  809. X  (setq calc-digit-map (make-keymap))
  810. X  (let ((i 0))
  811. X    (while (< i 128)
  812. X      (aset calc-digit-map i
  813. X        (if (eq (aref calc-mode-map i) 'undefined)
  814. X        'undefined 'calcDigit-nondigit))
  815. X      (setq i (1+ i))))
  816. X  (mapcar (function
  817. X       (lambda (x)
  818. X         (define-key calc-digit-map (char-to-string x) 'calcDigit-key)))
  819. X      "_0123456789.e+-:n#@oh'\"mspM")
  820. X  (mapcar (function
  821. X       (lambda (x)
  822. X         (define-key calc-digit-map (char-to-string x) 'calcDigit-letter)))
  823. X      "abcdfgijklqrtuvwxyzABCDEFGHIJKLNOPQRSTUVWXYZ")
  824. X  (define-key calc-digit-map "'" 'calcDigit-algebraic)
  825. X  (define-key calc-digit-map "\C-g" 'abort-recursive-edit)
  826. X  (calc-define-del calc-digit-map 'calcDigit-backspace)
  827. X)
  828. X
  829. X(put 'calc-mode 'mode-class 'special)
  830. X(put 'calc-trail-mode 'mode-class 'special)
  831. X
  832. X(defconst calc-mode-var-list '((calc-always-load-extensions nil)
  833. X                   (calc-line-numbering t)
  834. X                   (calc-line-breaking t)
  835. X                   (calc-display-just nil)
  836. X                   (calc-number-radix 10)
  837. X                   (calc-leading-zeros nil)
  838. X                   (calc-group-digits nil)
  839. X                   (calc-group-char ",")
  840. X                   (calc-point-char ".")
  841. X                   (calc-frac-format ":")
  842. X                   (calc-prefer-frac nil)
  843. X                   (calc-hms-format "%s@ %s' %s\"")
  844. X                   (calc-float-format (float 0))
  845. X                   (calc-full-float-format (float 0))
  846. X                   (calc-complex-format nil)
  847. X                   (calc-matrix-just center)
  848. X                   (calc-vector-commas ",")
  849. X                   (calc-vector-brackets "[]")
  850. X                   (calc-complex-mode cplx)
  851. X                   (calc-simplify-mode nil)
  852. X                   (calc-mapping-dir nil)
  853. X                   (calc-word-size 32)
  854. X                   (calc-previous-modulo nil)
  855. X                   (calc-internal-prec 12)
  856. X                   (calc-angle-mode deg)
  857. X                   (calc-algebraic-mode nil)
  858. X                   (calc-symbolic-mode nil)
  859. X                   (calc-integral-limit 3)
  860. X                   (calc-window-height 7)
  861. X                   (calc-language nil)
  862. X                   (calc-language-option nil)
  863. X                   (calc-display-trail t)
  864. X                   (calc-display-working-message lots)
  865. X                   (calc-auto-why nil)))
  866. X
  867. X(defconst calc-local-var-list '(calc-stack
  868. X                calc-stack-top
  869. X                calc-undo-list
  870. X                calc-redo-list
  871. X                calc-always-load-extensions
  872. X                calc-display-raw
  873. X                calc-line-numbering
  874. X                calc-line-breaking
  875. X                calc-display-just
  876. X                calc-auto-why
  877. X                calc-algebraic-mode
  878. X                calc-symbolic-mode
  879. X                calc-integral-limit
  880. X                calc-inverse-flag
  881. X                calc-hyperbolic-flag
  882. X                calc-angle-mode
  883. X                calc-number-radix
  884. X                calc-leading-zeros
  885. X                calc-group-digits
  886. X                calc-group-char
  887. X                calc-point-char
  888. X                calc-frac-format
  889. X                calc-prefer-frac
  890. X                calc-hms-format
  891. X                calc-float-format
  892. X                calc-full-float-format
  893. X                calc-complex-format
  894. X                calc-matrix-just
  895. X                calc-vector-commas
  896. X                calc-vector-brackets
  897. X                calc-complex-mode
  898. X                calc-simplify-mode
  899. X                calc-mapping-dir
  900. X                calc-word-size
  901. X                calc-internal-prec))
  902. X
  903. X
  904. X(defun calc-mode ()
  905. X  "Calculator major mode.
  906. X
  907. XThis is an RPN calculator featuring arbitrary-precision integer, rational,
  908. Xfloating-point, complex, matrix, and symbolic arithmetic.
  909. X
  910. XRPN calculation:  2 RET 3 +    produces 5.
  911. XAlgebraic style:  ' 2+3 RET    produces 5.
  912. X
  913. XOperators are +, -, *, /, ^ (power), % (modulo), n (change-sign).
  914. X
  915. XPress ? repeatedly for more complete help.
  916. X
  917. XNotations:  3.14e6     3.14 * 10^6
  918. X            _23        negative number -23
  919. X            17:3       the fraction 17/3
  920. X            5:2:3      the fraction 5 and 2/3
  921. X            16#12C     the integer 12C base 16 = 300 base 10
  922. X            8#177:100  the fraction 177:100 base 8 = 127:64 base 10
  923. X            (2, 4)     complex number 2 + 4i
  924. X            (2; 4)     polar complex number (r; theta)
  925. X            [1, 2, 3]  vector  ([[1, 2], [3, 4]] is a matrix)
  926. X            [1 .. 4)   semi-open interval, 1 <= x < 4
  927. X            2 +/- 3    (p key) number with mean 2, standard deviation 3
  928. X            2 mod 3    (M key) number 2 computed modulo 3
  929. X
  930. X\\{calc-mode-map}
  931. X"
  932. X  (interactive)
  933. X  (mapcar (function
  934. X       (lambda (v) (set-default v (symbol-value v)))) calc-local-var-list)
  935. X  (kill-all-local-variables)
  936. X  (use-local-map calc-mode-map)
  937. X  (mapcar (function (lambda (v) (make-local-variable v))) calc-local-var-list)
  938. X  (setq truncate-lines t)
  939. X  (setq buffer-read-only t)
  940. X  (setq major-mode 'calc-mode)
  941. X  (setq mode-name "Calculator")
  942. X  (if (memq 'top-of-stack (mapcar 'car-safe calc-stack))
  943. X      (setq calc-stack (copy-sequence calc-stack))
  944. X    (setq calc-stack '((top-of-stack 1))
  945. X      calc-stack-top 1))   ; backward compatibility
  946. X  (or calc-loaded-settings-file
  947. X      (string-match "\\.emacs" calc-settings-file)
  948. X      (progn
  949. X    (setq calc-loaded-settings-file t)
  950. X    (load calc-settings-file t)))   ; t = missing-ok
  951. X  (run-hooks 'calc-mode-hook)
  952. X  (calc-refresh t)
  953. X  (calc-set-mode-line)
  954. X  (if (and (boundp 'calc-defs)
  955. X       calc-defs)
  956. X      (progn
  957. X    (message "Evaluating calc-defs...")
  958. X    (eval (cons 'progn calc-defs))
  959. X    (setq calc-defs nil)
  960. X    (calc-refresh t)
  961. X    (calc-set-mode-line)))
  962. X)
  963. X
  964. X(defun calc-trail-mode (&optional buf)
  965. X  (interactive)
  966. X  (fundamental-mode)
  967. X  (use-local-map calc-mode-map)
  968. X  (setq major-mode 'calc-trail-mode)
  969. X  (setq mode-name "Calc Trail")
  970. X  (setq truncate-lines nil)
  971. X  (setq buffer-read-only t)
  972. X  (if buf
  973. X      (progn
  974. X    (make-local-variable 'calc-main-buffer)
  975. X    (setq calc-main-buffer buf)))
  976. X  (if (= (buffer-size) 0)
  977. X      (let ((buffer-read-only nil))
  978. X    (insert calc-version
  979. X        "\n")))
  980. X  (or (and calc-trail-pointer
  981. X       (eq (marker-buffer calc-trail-pointer) (current-buffer)))
  982. X      (save-excursion
  983. X    (goto-line 2)
  984. X    (setq calc-trail-pointer (point-marker))))
  985. X  (run-hooks 'calc-trail-mode-hook)
  986. X)
  987. X
  988. X(defun calc-create-buffer ()
  989. X  (set-buffer (get-buffer-create "*Calculator*"))
  990. X  (if (or (not (eq major-mode 'calc-mode))
  991. X      (and (boundp 'calc-defs) calc-defs))
  992. X      (calc-mode))
  993. X  (if calc-always-load-extensions
  994. X      (calc-extensions))
  995. X  (if calc-language
  996. X      (progn
  997. X    (calc-extensions)
  998. X    (calc-set-language calc-language calc-language-option t)))
  999. X)
  1000. X
  1001. X(defun calc (&optional arg no-display)
  1002. X  "The Emacs Calculator.  Full documentation is listed under \"calc-mode\"."
  1003. X  (interactive "P")
  1004. X  (or (fboundp 'calc-extensions)
  1005. X      (autoload 'calc-extensions "calc-ext"))
  1006. X  (if arg
  1007. X      (or (eq arg 0)
  1008. X      (progn
  1009. X        (calc-extensions)
  1010. X        (if (< (prefix-numeric-value arg) 0)
  1011. X        (calc-grab-region (region-beginning) (region-end)))))
  1012. X    (if (eq major-mode 'calc-mode)
  1013. X    (calc-quit)
  1014. X      (let ((oldbuf (current-buffer)))
  1015. X    (calc-create-buffer)
  1016. X    (if (get-buffer-window (current-buffer))
  1017. X        (select-window (get-buffer-window (current-buffer)))
  1018. X      (if (and (boundp 'calc-window-hook) calc-window-hook)
  1019. X          (run-hooks 'calc-window-hook)
  1020. X        (let ((w (get-largest-window)))
  1021. X          (if (and pop-up-windows
  1022. X               (> (window-height w)
  1023. X              (+ window-min-height calc-window-height 2)))
  1024. X          (progn
  1025. X            (setq w (split-window w
  1026. X                      (- (window-height w)
  1027. X                         calc-window-height 2)
  1028. X                      nil))
  1029. X            (set-window-buffer w (current-buffer))
  1030. X            (select-window w))
  1031. X        (pop-to-buffer (current-buffer))))))
  1032. X    (save-excursion
  1033. X      (let ((buf (current-buffer)))
  1034. X        (set-buffer (get-buffer-create "*Calc Trail*"))
  1035. X        (calc-trail-mode buf)
  1036. X        (and calc-display-trail
  1037. X         (= (window-width) (screen-width))
  1038. X         (calc-trail-display 1 t))))
  1039. X    (setq max-lisp-eval-depth (max max-lisp-eval-depth 1000))
  1040. X    (calc-summary)
  1041. X    (and calc-said-hello
  1042. X         (interactive-p)
  1043. X         (progn
  1044. X           (sit-for 2)
  1045. X           (message "")))
  1046. X    (setq calc-said-hello t)
  1047. X    (run-hooks 'calc-start-hook))))
  1048. X)
  1049. X
  1050. X(defun another-calc ()
  1051. X  "Create another, independent Calculator buffer."
  1052. X  (interactive)
  1053. X  (if (eq major-mode 'calc-mode)
  1054. X      (mapcar (function
  1055. X           (lambda (v)
  1056. X         (set-default v (symbol-value v)))) calc-local-var-list))
  1057. X  (set-buffer (generate-new-buffer "*Calculator*"))
  1058. X  (pop-to-buffer (current-buffer))
  1059. X  (calc-mode)
  1060. X)
  1061. X
  1062. X(defun calc-quit ()
  1063. X  "Close the Calculator window(s).
  1064. XThis does not destroy the Calculator buffers or forget the stack contents,
  1065. Xit only closes the windows."
  1066. X  (interactive)
  1067. X  (calc-select-buffer)
  1068. X  (run-hooks 'calc-end-hook)
  1069. X  (setq calc-undo-list nil calc-redo-list nil)
  1070. X  (mapcar (function
  1071. X       (lambda (v) (set-default v (symbol-value v)))) calc-local-var-list)
  1072. X  (let ((buf (current-buffer))
  1073. X    (tbuf (get-buffer-create "*Calc Trail*"))
  1074. X    (win (get-buffer-window (current-buffer))))
  1075. X    (if (and win
  1076. X         (< (window-height win) (1- (screen-height))))
  1077. X    (setq calc-window-height (- (window-height win) 2)))
  1078. X    (delete-windows-on buf)
  1079. X    (delete-windows-on tbuf)
  1080. X    (bury-buffer buf)
  1081. X    (bury-buffer tbuf))
  1082. X)
  1083. X
  1084. X(defun quick-calc ()
  1085. X  "Do a quick calculation in the minibuffer without invoking full Calculator."
  1086. X  (interactive)
  1087. X  (save-excursion
  1088. X    (calc-create-buffer)
  1089. X    (let* ((calc-command-flags nil)
  1090. X       (calc-language (if (memq calc-language '(nil big))
  1091. X                  'flat calc-language))
  1092. X       (calc-dollar-values calc-quick-prev-results)
  1093. X       (calc-dollar-used 0)
  1094. X       (alg-exp (calc-do-alg-entry "" "Quick calc: ")))
  1095. X      (let ((buf ""))
  1096. X    (setq calc-quick-prev-results alg-exp)
  1097. X    (while alg-exp
  1098. X      (setq buf (concat buf
  1099. X                (if calc-extensions-loaded
  1100. X                (math-format-value (car alg-exp) 1000)
  1101. X                  (math-format-flat-expr (car alg-exp) 0))
  1102. X                " ")
  1103. X        alg-exp (cdr alg-exp)))
  1104. X    (calc-handle-whys)
  1105. X    (message buf))))
  1106. X)
  1107. X
  1108. X(defun calc-summary ()
  1109. X  (interactive)
  1110. X  (message "Welcome to the GNU Emacs Calculator!  Press ? for help, q to quit.")
  1111. X)
  1112. X
  1113. X(defun calc-info ()
  1114. X  "Run the Emacs Info system on the Calculator documentation."
  1115. X  (interactive)
  1116. X  (require 'info)
  1117. X  (select-window (get-largest-window))
  1118. X  (Info-find-node calc-info-filename "Top")
  1119. X)
  1120. X
  1121. X(defun calc-help ()
  1122. X  (interactive)
  1123. X  (let ((msgs
  1124. X     '("Letter keys: Help, Info, Why; Xtended cmd; Yank; Quit"
  1125. X       "Letter keys: Negate; Precision; Store, Recall, Let"
  1126. X       "Letter keys: SHIFT + Undo, reDo, last-X; Inverse, Hyperbolic"
  1127. X       "Letter keys: SHIFT + sQrt; Sin, Cos, Tan; Exp, Ln, logB"
  1128. X       "Letter keys: SHIFT + Floor, Round; Abs, conJ, arG; Pi"
  1129. X       "Letter keys: SHIFT + Num-eval; More-recn; Kbd-macro"
  1130. X       "Other keys: +, -, *, /, ^, \\ (int div), : (frac div)"
  1131. X       "Other keys: & (1/x), | (concat), % (modulo), ! (factorial)"
  1132. X       "Other keys: ' (alg-entry), = (evaluate), ` (edit)"
  1133. X       "Other keys: RET (enter), DEL (drop), TAB (swap), M-TAB (roll)"
  1134. X       "Other keys: [ ] (vector), ( ) (complex); < > (hscroll)"
  1135. X       "Prefix keys: Algebra, Binary, Convert, Display, Kombinatorics"
  1136. X       "Prefix keys: Modes, Trail, Units, Vectors"
  1137. X       "Prefix keys: Z (user), SHIFT + Z (define-user)"
  1138. X       "Prefix keys: prefix + ? gives further help for that prefix"
  1139. X       "  Copyright (C) 1990 Dave Gillespie, daveg@csvax.caltech.edu")))
  1140. X    (setq calc-help-phase
  1141. X      (if (eq this-command last-command)
  1142. X          (% (1+ calc-help-phase) (1+ (length msgs)))
  1143. X        0))
  1144. X    (let ((msg (nth calc-help-phase msgs)))
  1145. X      (message "%s" (if msg
  1146. X            (concat msg ":"
  1147. X                (make-string (- (apply 'max
  1148. X                               (mapcar 'length msgs))
  1149. X                        (length msg)) 32)
  1150. X                "  [?=MORE]")
  1151. X              ""))))
  1152. X)
  1153. X(setq calc-help-phase 0)
  1154. X
  1155. X
  1156. X(defun calc-scroll-left (n)
  1157. X  "Horizontally scroll one half-screen to the left."
  1158. X  (interactive "P")
  1159. X  (scroll-left (or n (/ (window-width) 2)))
  1160. X)
  1161. X
  1162. X(defun calc-scroll-right (n)
  1163. X  "Horizontally scroll one half-screen to the right."
  1164. X  (interactive "P")
  1165. X  (scroll-right (or n (/ (window-width) 2)))
  1166. X)
  1167. X
  1168. X
  1169. X(defmacro calc-with-default-simplification (body)
  1170. X  (list 'let
  1171. X    '((calc-simplify-mode (and (not (memq calc-simplify-mode '(none num)))
  1172. X                   calc-simplify-mode)))
  1173. X    body)
  1174. X)
  1175. X
  1176. X
  1177. X
  1178. X
  1179. X;;;; Stack and buffer management.
  1180. X
  1181. X(defmacro calc-wrapper (&rest body)
  1182. X  (` (let ((calc-command-flags nil))
  1183. X       (unwind-protect
  1184. X       (progn
  1185. X         (, (append '(save-excursion (calc-select-buffer))
  1186. X            body
  1187. X            '((calc-finish-command)))))
  1188. X     (calc-cleanup-command))))
  1189. X)
  1190. X
  1191. X(defmacro calc-slow-wrapper (&rest body)
  1192. X  (` (let ((calc-command-flags (list 'clear-message)))
  1193. X       (if calc-display-working-message (message "Working..."))
  1194. X       (unwind-protect
  1195. X       (progn
  1196. X         (, (append '(save-excursion (calc-select-buffer))
  1197. X            body
  1198. X            '((calc-finish-command)))))
  1199. X     (calc-cleanup-command))))
  1200. X)
  1201. X
  1202. X(defun calc-set-command-flag (f)
  1203. X  (if (not (memq f calc-command-flags))
  1204. X      (setq calc-command-flags (cons f calc-command-flags)))
  1205. X)
  1206. X
  1207. X(defun calc-clear-command-flag (f)
  1208. X  (setq calc-command-flags (delq f calc-command-flags))
  1209. X)
  1210. X
  1211. X(defun calc-select-buffer ()
  1212. X  (if (not (eq major-mode 'calc-mode))
  1213. X      (if calc-main-buffer
  1214. X      (set-buffer calc-main-buffer)
  1215. X    (let ((buf (get-buffer "*Calculator*")))
  1216. X      (if buf
  1217. X          (set-buffer buf)
  1218. X        (error "Calculator buffer not available")))))
  1219. X)
  1220. X
  1221. X(defun calc-finish-command ()
  1222. X  (and (memq 'renum-stack calc-command-flags)
  1223. X       (calc-renumber-stack))
  1224. X  (and (memq 'clear-message calc-command-flags)
  1225. X       (message ""))
  1226. X)
  1227. X
  1228. X(defun calc-cleanup-command ()
  1229. X  (or (memq 'no-align calc-command-flags)
  1230. X      (calc-align-stack-window))
  1231. X  (or (memq 'keep-flags calc-command-flags)
  1232. X      (setq calc-inverse-flag nil
  1233. X        calc-hyperbolic-flag nil))
  1234. X  (calc-set-mode-line)
  1235. X)
  1236. X
  1237. X(defun calc-cursor-stack-index (&optional index)
  1238. X  (goto-char (point-max))
  1239. X  (forward-line (- (calc-substack-height (or index 1))))
  1240. X)
  1241. X
  1242. X(defun calc-stack-size ()
  1243. X  (- (length calc-stack) calc-stack-top)
  1244. X)
  1245. X
  1246. X(defun calc-substack-height (n)
  1247. X  (let ((sum 0)
  1248. X    (stack calc-stack))
  1249. X    (setq n (+ n calc-stack-top))
  1250. X    (while (and (> n 0) stack)
  1251. X      (setq sum (+ sum (nth 1 (car stack)))
  1252. X        n (1- n)
  1253. X        stack (cdr stack)))
  1254. X    sum)
  1255. X)
  1256. X
  1257. X(defun calc-set-mode-line ()
  1258. X  (save-excursion
  1259. X    (calc-select-buffer)
  1260. X    (let* ((fmt (car calc-float-format))
  1261. X       (figs (nth 1 calc-float-format))
  1262. X       (new-mode-string
  1263. X        (format "Calc%s: %d %s %-14s"
  1264. X            (if (and (> (length (buffer-name)) 12)
  1265. X                 (equal (substring (buffer-name) 0 12)
  1266. X                    "*Calculator*"))
  1267. X            (substring (buffer-name) 12)
  1268. X              "")
  1269. X            calc-internal-prec
  1270. X            (capitalize (symbol-name calc-angle-mode))
  1271. X            (concat
  1272. X             (cond ((= calc-number-radix 10) "")
  1273. X               ((= calc-number-radix 2) "Bin ")
  1274. X               ((= calc-number-radix 8) "Oct ")
  1275. X               ((= calc-number-radix 16) "Hex ")
  1276. X               (t (format "Radix%d " calc-number-radix)))
  1277. X             (if calc-algebraic-mode "Alg " "")
  1278. X             (if calc-symbolic-mode "Symb " "")
  1279. X             (cond ((eq calc-simplify-mode 'none) "NoSimp ")
  1280. X               ((eq calc-simplify-mode 'num) "NumSimp ")
  1281. X               ((eq calc-simplify-mode 'binary)
  1282. X                (format "BinSimp%d " calc-word-size))
  1283. X               ((eq calc-simplify-mode 'alg) "AlgSimp ")
  1284. X               ((eq calc-simplify-mode 'units) "UnitSimp ")
  1285. X               (t ""))
  1286. X             (cond ((null calc-language) "")
  1287. X               ((eq calc-language 'tex) "TeX ")
  1288. X               (t (concat
  1289. X                   (capitalize (symbol-name calc-language))
  1290. X                   " ")))
  1291. X             (if (eq calc-complex-mode 'polar) "Polar " "")
  1292. X             (if calc-prefer-frac "Frac " "")
  1293. X             (cond ((eq fmt 'float)
  1294. X                (if (zerop figs) "" (format "Norm%d " figs)))
  1295. X               ((eq fmt 'fix) (format "Fix%d " figs))
  1296. X               ((eq fmt 'sci)
  1297. X                (if (zerop figs) "Sci " (format "Sci%d " figs)))
  1298. X               ((eq fmt 'eng)
  1299. X                (if (zerop figs) "Eng " (format "Eng%d " figs))))
  1300. X             (if calc-inverse-flag "Inv " "")
  1301. X             (if calc-hyperbolic-flag "Hyp " "")
  1302. X             (if (/= calc-stack-top 1) "Narrow " "")
  1303. X             (apply 'concat calc-other-modes)))))
  1304. X      (if (equal new-mode-string mode-line-buffer-identification)
  1305. X      nil
  1306. X    (setq mode-line-buffer-identification new-mode-string)
  1307. X    (set-buffer-modified-p (buffer-modified-p)))))
  1308. X)
  1309. X
  1310. X(defun calc-align-stack-window ()
  1311. X  (let ((win (get-buffer-window (current-buffer))))
  1312. X    (if win
  1313. X    (progn
  1314. X      (calc-cursor-stack-index 0)
  1315. X      (vertical-motion (- 2 (window-height)))
  1316. X      (set-window-start win (point)))))
  1317. X  (calc-cursor-stack-index 0)
  1318. X  (if (looking-at " *\\.$")
  1319. X      (goto-char (1- (match-end 0))))
  1320. X)
  1321. X
  1322. X(defun calc-check-stack (n)
  1323. X  (if (> n (calc-stack-size))
  1324. X      (error "Too few elements on stack"))
  1325. X  (if (< n 0)
  1326. X      (error "Invalid argument"))
  1327. X)
  1328. X
  1329. X(defun calc-push (&rest vals)
  1330. X  (if (memq nil vals)
  1331. X      (error "Invalid operation")
  1332. X    (calc-push-list vals))
  1333. X)
  1334. X
  1335. X(defun calc-push-list (vals &optional m)
  1336. X  (while vals
  1337. X    (if calc-executing-macro
  1338. X    (let ((entry (list (car vals) 1))
  1339. X          (mm (+ (or m 1) calc-stack-top)))
  1340. X      (if (> mm 1)
  1341. X          (setcdr (nthcdr (- mm 2) calc-stack)
  1342. X              (cons entry (nthcdr (1- mm) calc-stack)))
  1343. X        (setq calc-stack (cons entry calc-stack))))
  1344. X      (save-excursion
  1345. X    (calc-select-buffer)
  1346. X    (let* ((val (car vals))
  1347. X           (fmt (math-format-stack-value val))
  1348. X           (entry (list val (calc-count-lines fmt)))
  1349. X           (mm (+ (or m 1) calc-stack-top)))
  1350. X      (calc-cursor-stack-index (1- (or m 1)))
  1351. X      (if (> mm 1)
  1352. X          (setcdr (nthcdr (- mm 2) calc-stack)
  1353. X              (cons entry (nthcdr (1- mm) calc-stack)))
  1354. X        (setq calc-stack (cons entry calc-stack)))
  1355. X      (let ((buffer-read-only nil))
  1356. X        (insert fmt "\n"))
  1357. X      (calc-record-undo (list 'push mm))
  1358. X      (calc-set-command-flag 'renum-stack))))
  1359. X    (setq vals (cdr vals)))
  1360. X)
  1361. X
  1362. X(defun calc-count-lines (s)
  1363. X  (let ((pos 0)
  1364. X    (num 1))
  1365. X    (while (setq newpos (string-match "\n" s pos))
  1366. X      (setq pos (1+ newpos)
  1367. X        num (1+ num)))
  1368. X    num)
  1369. X)
  1370. X
  1371. X(defun calc-pop-push-list (n vals)
  1372. X  (if (memq nil vals)
  1373. X      (error "Invalid operation"))
  1374. X  (calc-pop-stack n)
  1375. X  (calc-push-list vals)
  1376. X)
  1377. X
  1378. X(defun calc-pop-push (n &rest vals)
  1379. X  (calc-pop-push-list n vals)
  1380. X)
  1381. X
  1382. X(defun calc-pop-push-record-list (n prefix vals)
  1383. X  (if (and (consp vals)
  1384. X       (or (integerp (car vals))
  1385. X           (consp (car vals))))
  1386. X      (if (memq nil vals)
  1387. X      (error "Invalid operation"))
  1388. X    (and vals (setq vals (list vals))))
  1389. X  (calc-check-stack n)
  1390. X  (if prefix
  1391. X      (if vals
  1392. X      (calc-record-list vals prefix)
  1393. X    (calc-record nil prefix)))
  1394. X  (calc-pop-push-list n vals)
  1395. X)
  1396. X
  1397. X(defun calc-enter-result (n prefix vals)
  1398. X  (if (and (consp vals)
  1399. X       (or (integerp (car vals))
  1400. X           (consp (car vals))))
  1401. X      (setq vals (mapcar 'calc-normalize vals))
  1402. X    (setq vals (calc-normalize vals)))
  1403. X  (or (and (consp vals)
  1404. X       (or (integerp (car vals))
  1405. X           (consp (car vals))))
  1406. X      (setq vals (list vals)))
  1407. X  (if (equal vals '((nil)))
  1408. X      (setq vals nil))
  1409. X  (calc-pop-push-record-list n prefix vals)
  1410. X  (calc-handle-whys)
  1411. X)
  1412. X
  1413. X(defun calc-normalize (val)
  1414. X  (if (memq calc-simplify-mode '(nil none num))
  1415. X      (math-normalize val)
  1416. X    (calc-extensions)
  1417. X    (cond ((eq calc-simplify-mode 'binary)
  1418. X       (let ((s (math-normalize val)))
  1419. X         (if (math-realp s)
  1420. X         (math-clip (math-round s))
  1421. X           s)))
  1422. X      ((eq calc-simplify-mode 'alg)
  1423. X       (math-simplify val))
  1424. X      ((eq calc-simplify-mode 'ext)
  1425. X       (math-simplify-extended val))
  1426. X      ((eq calc-simplify-mode 'units)
  1427. X       (math-simplify-units val))))
  1428. X)
  1429. X
  1430. X(defun calc-handle-whys ()
  1431. X  (setq calc-why calc-next-why
  1432. X    calc-next-why nil)
  1433. X  (if (and calc-why calc-auto-why)
  1434. X      (progn
  1435. X    (calc-explain-why (car calc-why))
  1436. X    (calc-clear-command-flag 'clear-message)))
  1437. X)
  1438. X
  1439. X(defun calc-explain-why (why)
  1440. X  (let* ((pred (car why))
  1441. X     (msg (cond ((not pred) "Wrong type of argument")
  1442. X            ((stringp pred) pred)
  1443. X            ((eq pred 'integerp) "Integer expected")
  1444. X            ((eq pred 'natnump) "Nonnegative integer expected")
  1445. X            ((eq pred 'fixnump) "Small integer expected")
  1446. X            ((eq pred 'posp) "Positive number expected")
  1447. X            ((eq pred 'negp) "Negative number expected")
  1448. X            ((eq pred 'realp) "Real number expected")
  1449. X            ((eq pred 'anglep) "Real number expected")
  1450. X            ((eq pred 'hmsp) "HMS form expected")
  1451. X            ((eq pred 'numberp) "Number expected")
  1452. X            ((eq pred 'scalarp) "Number expected")
  1453. X            ((eq pred 'vectorp) "Vector or matrix expected")
  1454. X            ((eq pred 'numvecp) "Number or vector expected")
  1455. X            ((eq pred 'square-matrixp) "Square matrix expected")
  1456. X            ((eq pred 'objectp) "Number expected")
  1457. X            ((eq pred 'constp) "Constant expected")
  1458. X            ((eq pred 'range) "Argument out of range")
  1459. X            (t (format "%s expected" pred))))
  1460. X     (punc ": "))
  1461. X    (while (setq why (cdr why))
  1462. X      (setq msg (concat msg punc (if (stringp (car why))
  1463. X                     (car why)
  1464. X                   (math-format-flat-expr (car why) 0)))
  1465. X        punc ", "))
  1466. X    (message "%s" msg))
  1467. X)
  1468. X
  1469. X(defun calc-record-why (&rest stuff)
  1470. X  (setq calc-next-why (cons stuff calc-next-why))
  1471. X  nil
  1472. X)
  1473. X
  1474. X(defun calc-pop-push-record (n prefix &rest vals)
  1475. X  (calc-pop-push-record-list n prefix vals)
  1476. X)
  1477. X
  1478. X(defun calc-pop-stack (&optional n m)   ; pop N objects at level M of stack.
  1479. X  (or n (setq n 1))
  1480. X  (or m (setq m 1))
  1481. X  (let ((mm (+ m calc-stack-top)))
  1482. X    (if calc-executing-macro
  1483. X    (if (> mm 1)
  1484. X        (setcdr (nthcdr (- mm 2) calc-stack)
  1485. X            (nthcdr (+ n mm -1) calc-stack))
  1486. X      (setq calc-stack (nthcdr n calc-stack)))
  1487. X      (calc-record-undo (list 'pop mm (calc-top-list n m)))
  1488. X      (save-excursion
  1489. X    (calc-select-buffer)
  1490. X    (let ((buffer-read-only nil))
  1491. X      (if (> mm 1)
  1492. X          (progn
  1493. X        (calc-cursor-stack-index (1- m))
  1494. X        (let ((bot (point)))
  1495. X          (calc-cursor-stack-index (+ n m -1))
  1496. X          (delete-region (point) bot))
  1497. X        (setcdr (nthcdr (- mm 2) calc-stack)
  1498. X            (nthcdr (+ n mm -1) calc-stack)))
  1499. X        (calc-cursor-stack-index n)
  1500. X        (setq calc-stack (nthcdr n calc-stack))
  1501. X        (delete-region (point) (point-max)))
  1502. X      (calc-set-command-flag 'renum-stack)))))
  1503. X)
  1504. X
  1505. X(defun calc-top (&optional n)
  1506. X  "Get the Nth element of the stack (N=1 is the top element)."
  1507. X  (or n (setq n 1))
  1508. X  (calc-check-stack n)
  1509. X  (car-safe (nth (+ n calc-stack-top -1) calc-stack))
  1510. X)
  1511. X
  1512. X(defun calc-top-n (&optional n)    ; in case precision has changed
  1513. X  (math-check-complete (calc-normalize (calc-top n)))
  1514. X)
  1515. X
  1516. X(defun calc-top-list (&optional n m)
  1517. X  (or n (setq n 1))
  1518. X  (or m (setq m 1))
  1519. X  (calc-check-stack (+ n m -1))
  1520. X  (and (> n 0)
  1521. X       (let ((top (copy-sequence (nthcdr (+ m calc-stack-top -1)
  1522. X                     calc-stack))))
  1523. X     (setcdr (nthcdr (1- n) top) nil)
  1524. X     (nreverse (mapcar 'car-safe top))))
  1525. X)
  1526. X
  1527. X(defun calc-top-list-n (&optional n m)
  1528. X  (mapcar 'math-check-complete
  1529. X      (mapcar 'calc-normalize (calc-top-list n m)))
  1530. X)
  1531. X
  1532. X(defun calc-roll-down-stack (n &optional m)
  1533. X  (if (< n 0)
  1534. X      (calc-roll-up-stack (- n) m)
  1535. X    (if (or (= n 0) (> n (calc-stack-size))) (setq n (calc-stack-size)))
  1536. X    (or m (setq m 1))
  1537. X    (and (> n 1)
  1538. X     (< m n)
  1539. X     (calc-pop-push-list n
  1540. X                 (append (calc-top-list m 1)
  1541. X                     (calc-top-list (- n m) (1+ m))))))
  1542. X)
  1543. X
  1544. X(defun calc-roll-up-stack (n &optional m)
  1545. X  (if (< n 0)
  1546. X      (calc-roll-down-stack (- n) m)
  1547. X    (if (or (= n 0) (> n (calc-stack-size))) (setq n (calc-stack-size)))
  1548. X    (or m (setq m 1))
  1549. X    (and (> n 1)
  1550. X     (< m n)
  1551. X     (calc-pop-push-list n
  1552. X                 (append (calc-top-list (- n m) 1)
  1553. X                     (calc-top-list m (- n m -1))))))
  1554. X)
  1555. X
  1556. X(defun calc-renumber-stack ()
  1557. X  (if calc-line-numbering
  1558. X      (save-excursion
  1559. X    (calc-cursor-stack-index 0)
  1560. X    (let ((lnum 1)
  1561. X          (buffer-read-only nil))
  1562. X      (if (re-search-forward "^[0-9]+:" nil t)
  1563. X          (progn
  1564. X        (beginning-of-line)
  1565. X        (while (re-search-forward "^[0-9]+:" nil t)
  1566. X          (let ((buffer-read-only nil))
  1567. X            (beginning-of-line)
  1568. X            (delete-char 4)
  1569. X            (insert "    ")))
  1570. X        (calc-cursor-stack-index 0)))
  1571. X      (while (re-search-backward "^[0-9]+:" nil t)
  1572. X        (delete-char 4)
  1573. X        (if (> lnum 999)
  1574. X        (insert (format "%03d:" (% lnum 1000)))
  1575. X          (let ((prefix (int-to-string lnum)))
  1576. X        (insert prefix ":" (make-string (- 3 (length prefix)) 32))))
  1577. X        (beginning-of-line)
  1578. X        (setq lnum (1+ lnum))))))
  1579. X)
  1580. X
  1581. X(defun calc-refresh (&optional align)
  1582. X  "Refresh the contents of the Calculator buffer from memory."
  1583. X  (interactive)
  1584. X  (if (and (eq major-mode 'calc-mode)
  1585. X       (not calc-executing-macro))
  1586. X      (let ((buffer-read-only nil)
  1587. X        (save-point (point))
  1588. X        (save-mark (mark))
  1589. X        (save-aligned (looking-at "\\.$"))
  1590. X        (thing calc-stack))
  1591. X    (erase-buffer)
  1592. X    (insert "--- Emacs Calculator Mode ---\n")
  1593. X    (while thing
  1594. X      (goto-char (point-min))
  1595. X      (forward-line 1)
  1596. X      (let ((fmt (math-format-stack-value (car (car thing)))))
  1597. X        (setcar (cdr (car thing)) (calc-count-lines fmt))
  1598. X        (insert fmt "\n"))
  1599. X      (setq thing (cdr thing)))
  1600. X    (calc-renumber-stack)
  1601. X    (if (or align save-aligned)
  1602. X        (calc-align-stack-window)
  1603. X      (goto-char save-point))
  1604. X    (set-mark save-mark)))
  1605. X  (setq calc-refresh-count (1+ calc-refresh-count))
  1606. X)
  1607. X(setq calc-refresh-count 0)
  1608. X
  1609. X(defun calc-realign ()
  1610. X  "Realign Calc window with cursor and top-of-stack at the bottom."
  1611. X  (interactive)
  1612. X  (calc-wrapper)
  1613. X)
  1614. X
  1615. X
  1616. X
  1617. X;;;; The Calc Trail buffer.
  1618. X
  1619. X(defun calc-check-trail-aligned ()
  1620. X  (save-excursion
  1621. X    (let ((win (get-buffer-window (current-buffer))))
  1622. X      (and win
  1623. X       (pos-visible-in-window-p (1- (point-max)) win)
  1624. X       ; (not (pos-visible-in-window-p (point-max) win))
  1625. X       )))
  1626. X)
  1627. X
  1628. X(defmacro math-showing-full-precision (body)
  1629. X  (list 'let
  1630. X    '((calc-float-format calc-full-float-format))
  1631. X    body)
  1632. SHAR_EOF
  1633. echo "End of part 1"
  1634. echo "File calc.el is continued in part 2"
  1635. echo "2" > s2_seq_.tmp
  1636. exit 0
  1637.