1 ;;; calc-store.el --- value storage functions for Calc
3 ;; Copyright (C) 1990, 1991, 1992, 1993, 2001 Free Software Foundation, Inc.
5 ;; Author: David Gillespie <daveg@synaptics.com>
6 ;; Maintainer: Jay Belanger <belanger@truman.edu>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY. No author or distributor
12 ;; accepts responsibility to anyone for the consequences of using it
13 ;; or for whether it serves any particular purpose or works at all,
14 ;; unless he says so in writing. Refer to the GNU Emacs General Public
15 ;; License for full details.
17 ;; Everyone is granted permission to copy, modify and redistribute
18 ;; GNU Emacs, but only under the conditions described in the
19 ;; GNU Emacs General Public License. A copy of this license is
20 ;; supposed to have been given to you along with GNU Emacs so you
21 ;; can know your rights and responsibilities. It should be in a
22 ;; file named COPYING. Among other things, the copyright notice
23 ;; and this notice must be preserved on all copies.
29 ;; This file is autoloaded from calc-ext.el.
36 (defvar calc-store-keep nil
)
37 (defun calc-store (&optional var
)
39 (let ((calc-store-keep t
))
40 (calc-store-into var
)))
42 (defvar calc-given-value-flag nil
)
43 (defvar calc-given-value
)
45 (defun calc-store-into (&optional var
)
48 (let ((calc-given-value nil
)
49 (calc-given-value-flag 1))
50 (or var
(setq var
(calc-read-var-name "Store: " t
)))
52 (let ((found (assq var
'( ( + . calc-store-plus
)
53 ( - . calc-store-minus
)
54 ( * . calc-store-times
)
55 ( / . calc-store-div
)
56 ( ^ . calc-store-power
)
57 ( | . calc-store-concat
) ))))
60 (calc-store-value var
(or calc-given-value
(calc-top 1))
61 "" calc-given-value-flag
)
62 (message "Stored to variable \"%s\"" (calc-var-name var
))))
63 (setq var
(calc-is-assignments (calc-top 1)))
66 (calc-store-value (car (car var
)) (cdr (car var
))
67 (if (not (cdr var
)) "")
68 (if (not (cdr var
)) 1))
69 (setq var
(cdr var
))))))))
71 (defun calc-store-plus (&optional var
)
73 (calc-store-binary var
"+" '+))
75 (defun calc-store-minus (&optional var
)
77 (calc-store-binary var
"-" '-
))
79 (defun calc-store-times (&optional var
)
81 (calc-store-binary var
"*" '*))
83 (defun calc-store-div (&optional var
)
85 (calc-store-binary var
"/" '/))
87 (defun calc-store-power (&optional var
)
89 (calc-store-binary var
"^" '^
))
91 (defun calc-store-concat (&optional var
)
93 (calc-store-binary var
"|" '|
))
95 (defun calc-store-neg (n &optional var
)
97 (calc-store-binary var
"n" '/ (- n
)))
99 (defun calc-store-inv (n &optional var
)
101 (calc-store-binary var
"&" '^
(- n
)))
103 (defun calc-store-incr (n &optional var
)
105 (calc-store-binary var
"n" '-
(- n
)))
107 (defun calc-store-decr (n &optional var
)
109 (calc-store-binary var
"n" '- n
))
111 (defun calc-store-value (var value tag
&optional pop
)
113 (let ((old (calc-var-value var
)))
115 (if pop
(or calc-store-keep
(calc-pop-stack pop
)))
116 (calc-record-undo (list 'store
(symbol-name var
) old
))
118 (let ((calc-full-trail-vectors nil
))
119 (calc-record value
(format ">%s%s" tag
(calc-var-name var
)))))
120 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
121 (eq (car-safe old
) 'special-const
)
122 (message "(Note: Built-in definition of %s has been lost)" var
))
123 (and (memq var
'(var-inf var-uinf var-nan
))
125 (message "(Note: %s has built-in meanings which may interfere)"
127 (calc-refresh-evaltos var
))))
129 (defun calc-var-name (var)
130 (if (symbolp var
) (setq var
(symbol-name var
)))
131 (if (string-match "\\`var-." var
)
135 (defun calc-store-binary (var tag func
&optional val
)
137 (let ((calc-simplify-mode (if (eq calc-simplify-mode
'none
)
138 'num calc-simplify-mode
))
139 (value (or val
(calc-top 1))))
140 (or var
(setq var
(calc-read-var-name (format "Store %s: " tag
))))
142 (let ((old (calc-var-value var
)))
144 (error "No such variable: \"%s\"" (calc-var-name var
)))
146 (setq old
(math-read-expr old
)))
147 (if (eq (car-safe old
) 'error
)
148 (error "Bad format in variable contents: %s" (nth 2 old
)))
149 (calc-store-value var
150 (calc-normalize (if (calc-is-inverse)
151 (list func value old
)
152 (list func old value
)))
153 tag
(and (not val
) 1))
154 (message "Stored to variable \"%s\"" (calc-var-name var
)))))))
156 (defvar calc-var-name-map nil
"Keymap for reading Calc variable names.")
157 (if calc-var-name-map
159 (setq calc-var-name-map
(copy-keymap minibuffer-local-completion-map
))
160 (define-key calc-var-name-map
" " 'self-insert-command
)
163 (define-key calc-var-name-map
(char-to-string x
)
168 (define-key calc-var-name-map
(char-to-string x
)
172 (defvar calc-store-opers
)
174 (defun calc-read-var-name (prompt &optional calc-store-opers
)
175 (setq calc-given-value nil
176 calc-aborted-prefix nil
)
179 (let ((minibuffer-completion-table
180 (mapcar (lambda (x) (substring x
4))
181 (all-completions "var-" obarray
)))
182 (minibuffer-completion-predicate
183 (lambda (x) (boundp (intern (concat "var-" x
)))))
184 (minibuffer-completion-confirm t
))
185 (read-from-minibuffer prompt nil calc-var-name-map nil
)))))
186 (setq calc-aborted-prefix
"")
187 (and (not (equal var
"var-"))
188 (if (string-match "\\`\\([-a-zA-Z0-9]+\\) *:?=" var
)
189 (if (null calc-given-value-flag
)
190 (error "Assignment is not allowed in this command")
191 (let ((svar (intern (substring var
0 (match-end 1)))))
192 (setq calc-given-value-flag
0
193 calc-given-value
(math-read-expr
194 (substring var
(match-end 0))))
195 (if (eq (car-safe calc-given-value
) 'error
)
196 (error "Bad format: %s" (nth 2 calc-given-value
)))
197 (setq calc-given-value
(math-evaluate-expr calc-given-value
))
201 (defun calcVar-digit ()
203 (if (calc-minibuffer-contains "\\'")
204 (if (eq calc-store-opers
0)
207 (self-insert-and-exit))
208 (self-insert-command 1)))
210 (defun calcVar-oper ()
212 (if (and (eq calc-store-opers t
)
213 (calc-minibuffer-contains "\\'"))
216 (self-insert-and-exit))
217 (self-insert-command 1)))
219 (defun calc-store-map (&optional oper var
)
222 (let* ((sel-mode nil
)
223 (calc-dollar-values (mapcar 'calc-get-stack-element
224 (nthcdr calc-stack-top calc-stack
)))
226 (oper (or oper
(calc-get-operator "Store Mapping")))
228 (or var
(setq var
(calc-read-var-name (format "Store Mapping %s: "
231 (let ((old (or (calc-var-value var
)
232 (error "No such variable: \"%s\""
233 (calc-var-name var
))))
234 (calc-simplify-mode (if (eq calc-simplify-mode
'none
)
235 'num calc-simplify-mode
))
236 (values (and (> nargs
1)
237 (calc-top-list (1- nargs
) (1+ calc-dollar-used
)))))
238 (message "Working...")
239 (calc-set-command-flag 'clear-message
)
241 (setq old
(math-read-expr old
)))
242 (if (eq (car-safe old
) 'error
)
243 (error "Bad format in variable contents: %s" (nth 2 old
)))
244 (setq values
(if (calc-is-inverse)
245 (append values
(list old
))
246 (append (list old
) values
)))
247 (calc-store-value var
248 (calc-normalize (cons (nth 1 oper
) values
))
250 (+ calc-dollar-used
(1- nargs
))))))))
252 (defun calc-store-exchange (&optional var
)
255 (let ((calc-given-value nil
)
256 (calc-given-value-flag 1)
258 (or var
(setq var
(calc-read-var-name "Exchange with: ")))
260 (let ((value (calc-var-value var
)))
262 (error "No such variable: \"%s\"" (calc-var-name var
)))
263 (if (eq (car-safe value
) 'special-const
)
264 (error "%s is a special constant" var
))
265 (setq top
(or calc-given-value
(calc-top 1)))
266 (calc-store-value var top nil
)
267 (calc-pop-push-record calc-given-value-flag
268 (concat "<>" (calc-var-name var
)) value
))))))
270 (defun calc-unstore (&optional var
)
273 (or var
(setq var
(calc-read-var-name "Unstore: ")))
276 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
277 (eq (car-safe (calc-var-value var
)) 'special-const
)
278 (message "(Note: Built-in definition of %s has been lost)" var
))
279 (if (and (boundp var
) (symbol-value var
))
280 (message "Unstored variable \"%s\"" (calc-var-name var
))
281 (message "Variable \"%s\" remains unstored" (calc-var-name var
)))
283 (calc-refresh-evaltos var
)))))
285 (defun calc-let (&optional var
)
288 (let* ((calc-given-value nil
)
289 (calc-given-value-flag 1)
291 (or var
(setq var
(calc-read-var-name "Let variable: ")))
293 (setq value calc-given-value
295 (setq value
(calc-top 1)
298 (list (cons var value
))
299 (calc-is-assignments value
)))
301 (calc-pop-push-record
302 (1+ calc-given-value-flag
)
303 (concat "=" (calc-var-name (car (car var
))))
304 (let ((saved-val (mapcar (function
306 (and (boundp (car v
))
307 (symbol-value (car v
)))))
312 (set (car (car vv
)) (calc-normalize (cdr (car vv
))))
313 (calc-refresh-evaltos (car (car vv
)))
315 (math-evaluate-expr thing
))
318 (set (car (car var
)) (car saved-val
))
319 (makunbound (car (car var
))))
320 (setq saved-val
(cdr saved-val
)
322 (calc-handle-whys))))))))
324 (defun calc-is-assignments (value)
325 (if (memq (car-safe value
) '(calcFunc-eq calcFunc-assign
))
326 (and (eq (car-safe (nth 1 value
)) 'var
)
327 (list (cons (nth 2 (nth 1 value
)) (nth 2 value
))))
328 (if (eq (car-safe value
) 'vec
)
330 (while (and (setq value
(cdr value
))
331 (memq (car-safe (car value
))
332 '(calcFunc-eq calcFunc-assign
))
333 (eq (car-safe (nth 1 (car value
))) 'var
))
334 (setq vv
(cons (cons (nth 2 (nth 1 (car value
)))
340 (defun calc-recall (&optional var
)
343 (or var
(setq var
(calc-read-var-name "Recall: ")))
345 (let ((value (calc-var-value var
)))
347 (error "No such variable: \"%s\"" (calc-var-name var
)))
349 (setq value
(math-read-expr value
)))
350 (if (eq (car-safe value
) 'error
)
351 (error "Bad format in variable contents: %s" (nth 2 value
)))
352 (setq value
(calc-normalize value
))
353 (let ((calc-full-trail-vectors nil
))
354 (calc-record value
(concat "<" (calc-var-name var
))))
355 (calc-push value
)))))
357 (defun calc-store-quick ()
359 (calc-store (intern (format "var-q%c" last-command-char
))))
361 (defun calc-store-into-quick ()
363 (calc-store-into (intern (format "var-q%c" last-command-char
))))
365 (defun calc-recall-quick ()
367 (calc-recall (intern (format "var-q%c" last-command-char
))))
369 (defun calc-copy-variable (&optional var1 var2
)
372 (or var1
(setq var1
(calc-read-var-name "Copy variable: ")))
374 (let ((value (calc-var-value var1
)))
376 (error "No such variable: \"%s\"" (calc-var-name var1
)))
377 (or var2
(setq var2
(calc-read-var-name
378 (format "Copy variable: %s, to: "
379 (calc-var-name var1
)))))
381 (calc-store-value var2 value
""))))))
383 (defvar calc-last-edited-variable nil
)
384 (defun calc-edit-variable (&optional var
)
387 (or var
(setq var
(calc-read-var-name
388 (if calc-last-edited-variable
389 (format "Edit: (default %s) "
390 (calc-var-name calc-last-edited-variable
))
392 (or var
(setq var calc-last-edited-variable
))
394 (let* ((value (calc-var-value var
)))
395 (if (eq (car-safe value
) 'special-const
)
396 (error "%s is a special constant" var
))
397 (setq calc-last-edited-variable var
)
398 (calc-edit-mode (list 'calc-finish-stack-edit
(list 'quote var
))
400 (concat "Editing variable `" (calc-var-name var
) "'. "))
402 (insert (math-format-nice-expr value
(frame-width)) "\n")))))
403 (calc-show-edit-buffer))
405 (defun calc-edit-Decls ()
407 (calc-edit-variable 'var-Decls
))
409 (defun calc-edit-EvalRules ()
411 (calc-edit-variable 'var-EvalRules
))
413 (defun calc-edit-FitRules ()
415 (calc-edit-variable 'var-FitRules
))
417 (defun calc-edit-GenCount ()
419 (calc-edit-variable 'var-GenCount
))
421 (defun calc-edit-Holidays ()
423 (calc-edit-variable 'var-Holidays
))
425 (defun calc-edit-IntegLimit ()
427 (calc-edit-variable 'var-IntegLimit
))
429 (defun calc-edit-LineStyles ()
431 (calc-edit-variable 'var-LineStyles
))
433 (defun calc-edit-PointStyles ()
435 (calc-edit-variable 'var-PointStyles
))
437 (defun calc-edit-PlotRejects ()
439 (calc-edit-variable 'var-PlotRejects
))
441 (defun calc-edit-AlgSimpRules ()
443 (calc-edit-variable 'var-AlgSimpRules
))
445 (defun calc-edit-TimeZone ()
447 (calc-edit-variable 'var-TimeZone
))
449 (defun calc-edit-Units ()
451 (calc-edit-variable 'var-Units
))
453 (defun calc-edit-ExtSimpRules ()
455 (calc-edit-variable 'var-ExtSimpRules
))
457 (defun calc-declare-variable (&optional var
)
460 (or var
(setq var
(calc-read-var-name "Declare: " 0)))
461 (or var
(setq var
'var-All
))
462 (let* (dp decl def row rp
)
463 (or (and (calc-var-value 'var-Decls
)
464 (eq (car-safe var-Decls
) 'vec
))
465 (setq var-Decls
(list 'vec
)))
467 (while (and (setq dp
(cdr dp
))
468 (or (not (eq (car-safe (car dp
)) 'vec
))
469 (/= (length (car dp
)) 3)
471 (setq row
(nth 1 (car dp
))
473 (if (eq (car-safe row
) 'vec
)
476 (and (setq rp
(cdr rp
))
477 (or (not (eq (car-safe (car rp
)) 'var
))
478 (not (eq (nth 2 (car rp
)) var
)))))
480 (if (or (not (eq (car-safe row
) 'var
))
481 (not (eq (nth 2 row
) var
)))
484 (calc-unread-command ?\C-a
)
485 (setq decl
(read-string (format "Declare: %s to be: " (calc-var-name var
))
487 (math-format-flat-expr (nth 2 (car dp
)) 0))))
488 (setq decl
(and (string-match "[^ \t]" decl
)
489 (math-read-exprs decl
)))
490 (if (eq (car-safe decl
) 'error
)
491 (error "Bad format in declaration: %s" (nth 2 decl
)))
493 (setq decl
(cons 'vec decl
))
494 (setq decl
(car decl
)))
495 (and (eq (car-safe decl
) 'vec
)
497 (setq decl
(nth 1 decl
)))
498 (calc-record (append '(vec) (list (math-build-var-name var
))
499 (and decl
(list decl
)))
501 (setq var-Decls
(copy-sequence var-Decls
))
502 (if (eq (car-safe row
) 'vec
)
504 (setcdr row
(delq rp
(cdr row
)))
506 (setq var-Decls
(delq (car dp
) var-Decls
))))
507 (setq var-Decls
(delq (car dp
) var-Decls
)))
510 (setq dp
(and (not (eq var
'var-All
)) var-Decls
))
511 (while (and (setq dp
(cdr dp
))
512 (or (not (eq (car-safe (car dp
)) 'vec
))
513 (/= (length (car dp
)) 3)
514 (not (equal (nth 2 (car dp
)) decl
)))))
516 (setcar (cdr (car dp
))
517 (append (if (eq (car-safe (nth 1 (car dp
))) 'vec
)
519 (list 'vec
(nth 1 (car dp
))))
520 (list (math-build-var-name var
))))
521 (setq var-Decls
(append var-Decls
523 (math-build-var-name var
)
525 (calc-refresh-evaltos 'var-Decls
))))
527 (defvar calc-dont-insert-variables
'(var-FitRules var-FactorRules
528 var-CommuteRules var-JumpRules
529 var-DistribRules var-MergeRules
530 var-NegateRules var-InvertRules
532 var-TimeZone var-PlotRejects
533 var-PlotData1 var-PlotData2
534 var-PlotData3 var-PlotData4
535 var-PlotData5 var-PlotData6
538 ;; The variable calc-pv-pos is local to calc-permanent-variable, but
539 ;; used by calc-insert-permanent-variable, which is called by
540 ;; calc-permanent-variable.
543 (defun calc-permanent-variable (&optional var
)
546 (or var
(setq var
(calc-read-var-name "Save variable (default=all): ")))
548 (and var
(or (and (boundp var
) (symbol-value var
))
549 (error "No such variable")))
550 (set-buffer (find-file-noselect (substitute-in-file-name
551 calc-settings-file
)))
553 (calc-insert-permanent-variable var
)
556 (and (string-match "\\`var-" (symbol-name x
))
557 (not (memq x calc-dont-insert-variables
))
559 (not (eq (car-safe (symbol-value x
)) 'special-const
))
560 (calc-insert-permanent-variable x
))))))
565 (defun calc-insert-permanent-variable (var)
566 (goto-char (point-min))
567 (if (search-forward (concat "(setq " (symbol-name var
) " '") nil t
)
569 (setq calc-pv-pos
(point-marker))
571 (if (looking-at ";;; Variable .* stored by Calc on ")
573 (delete-region (match-end 0) (progn (end-of-line) (point)))
574 (insert (current-time-string))))
575 (goto-char (- calc-pv-pos
8 (length (symbol-name var
))))
578 (delete-region calc-pv-pos
(point)))
579 (goto-char (point-max))
580 (insert "\n;;; Variable \""
582 "\" stored by Calc on "
583 (current-time-string)
588 (insert (prin1-to-string (calc-var-value var
)))
591 (defun calc-insert-variables (buf)
592 (interactive "bBuffer in which to save variable values: ")
597 (and (string-match "\\`var-" (symbol-name x
))
598 (not (memq x calc-dont-insert-variables
))
600 (not (eq (car-safe (symbol-value x
)) 'special-const
))
601 (or (not (eq x
'var-Decls
))
602 (not (equal var-Decls
'(vec))))
603 (or (not (eq x
'var-Holidays
))
604 (not (equal var-Holidays
'(vec (var sat var-sat
)
605 (var sun var-sun
)))))
611 (if (memq calc-language
'(nil big
))
614 (math-format-value (symbol-value x
) 100000)))
617 (defun calc-assign (arg)
620 (calc-binary-op ":=" 'calcFunc-assign arg
)))
622 (defun calc-evalto (arg)
625 (calc-unary-op "=>" 'calcFunc-evalto arg
)))
627 (defun calc-subscript (arg)
630 (calc-binary-op "sub" 'calcFunc-subscr arg
)))
632 (provide 'calc-store
)
634 ;;; arch-tag: 2fbfec82-a521-42ca-bcd8-4f254ae6313e
635 ;;; calc-store.el ends here