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: Colin Walters <walters@debian.org>
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.
34 (defun calc-Need-calc-store () nil
)
39 (defvar calc-store-keep nil
)
40 (defun calc-store (&optional var
)
42 (let ((calc-store-keep t
))
43 (calc-store-into var
)))
45 (defvar calc-given-value-flag nil
)
46 (defun calc-store-into (&optional var
)
49 (let ((calc-given-value nil
)
50 (calc-given-value-flag 1))
51 (or var
(setq var
(calc-read-var-name "Store: " t
)))
53 (let ((found (assq var
'( ( + . calc-store-plus
)
54 ( - . calc-store-minus
)
55 ( * . calc-store-times
)
56 ( / . calc-store-div
)
57 ( ^ . calc-store-power
)
58 ( | . calc-store-concat
) ))))
61 (calc-store-value var
(or calc-given-value
(calc-top 1))
62 "" calc-given-value-flag
)
63 (message "Stored to variable \"%s\"" (calc-var-name var
))))
64 (setq var
(calc-is-assignments (calc-top 1)))
67 (calc-store-value (car (car var
)) (cdr (car var
))
68 (if (not (cdr var
)) "")
69 (if (not (cdr var
)) 1))
70 (setq var
(cdr var
))))))))
72 (defun calc-store-plus (&optional var
)
74 (calc-store-binary var
"+" '+))
76 (defun calc-store-minus (&optional var
)
78 (calc-store-binary var
"-" '-
))
80 (defun calc-store-times (&optional var
)
82 (calc-store-binary var
"*" '*))
84 (defun calc-store-div (&optional var
)
86 (calc-store-binary var
"/" '/))
88 (defun calc-store-power (&optional var
)
90 (calc-store-binary var
"^" '^
))
92 (defun calc-store-concat (&optional var
)
94 (calc-store-binary var
"|" '|
))
96 (defun calc-store-neg (n &optional var
)
98 (calc-store-binary var
"n" '/ (- n
)))
100 (defun calc-store-inv (n &optional var
)
102 (calc-store-binary var
"&" '^
(- n
)))
104 (defun calc-store-incr (n &optional var
)
106 (calc-store-binary var
"n" '-
(- n
)))
108 (defun calc-store-decr (n &optional var
)
110 (calc-store-binary var
"n" '- n
))
112 (defun calc-store-value (var value tag
&optional pop
)
114 (let ((old (calc-var-value var
)))
116 (if pop
(or calc-store-keep
(calc-pop-stack pop
)))
117 (calc-record-undo (list 'store
(symbol-name var
) old
))
119 (let ((calc-full-trail-vectors nil
))
120 (calc-record value
(format ">%s%s" tag
(calc-var-name var
)))))
121 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
122 (eq (car-safe old
) 'special-const
)
123 (message "(Note: Built-in definition of %s has been lost)" var
))
124 (and (memq var
'(var-inf var-uinf var-nan
))
126 (message "(Note: %s has built-in meanings which may interfere)"
128 (calc-refresh-evaltos var
))))
130 (defun calc-var-name (var)
131 (if (symbolp var
) (setq var
(symbol-name var
)))
132 (if (string-match "\\`var-." var
)
136 (defun calc-store-binary (var tag func
&optional val
)
138 (let ((calc-simplify-mode (if (eq calc-simplify-mode
'none
)
139 'num calc-simplify-mode
))
140 (value (or val
(calc-top 1))))
141 (or var
(setq var
(calc-read-var-name (format "Store %s: " tag
))))
143 (let ((old (calc-var-value var
)))
145 (error "No such variable: \"%s\"" (calc-var-name var
)))
147 (setq old
(math-read-expr old
)))
148 (if (eq (car-safe old
) 'error
)
149 (error "Bad format in variable contents: %s" (nth 2 old
)))
150 (calc-store-value var
151 (calc-normalize (if (calc-is-inverse)
152 (list func value old
)
153 (list func old value
)))
154 tag
(and (not val
) 1))
155 (message "Stored to variable \"%s\"" (calc-var-name var
)))))))
157 (defun calc-read-var-name (prompt &optional calc-store-opers
)
158 (setq calc-given-value nil
159 calc-aborted-prefix nil
)
160 (let ((var (let ((minibuffer-completion-table obarray
)
161 (minibuffer-completion-predicate 'boundp
)
162 (minibuffer-completion-confirm t
))
163 (read-from-minibuffer prompt
"var-" calc-var-name-map nil
))))
164 (setq calc-aborted-prefix
"")
165 (and (not (equal var
""))
166 (not (equal var
"var-"))
167 (if (string-match "\\`\\([-a-zA-Z0-9]+\\) *:?=" var
)
168 (if (null calc-given-value-flag
)
169 (error "Assignment is not allowed in this command")
170 (let ((svar (intern (substring var
0 (match-end 1)))))
171 (setq calc-given-value-flag
0
172 calc-given-value
(math-read-expr
173 (substring var
(match-end 0))))
174 (if (eq (car-safe calc-given-value
) 'error
)
175 (error "Bad format: %s" (nth 2 calc-given-value
)))
176 (setq calc-given-value
(math-evaluate-expr calc-given-value
))
180 (defvar calc-var-name-map nil
"Keymap for reading Calc variable names.")
181 (if calc-var-name-map
183 (setq calc-var-name-map
(copy-keymap minibuffer-local-completion-map
))
184 (define-key calc-var-name-map
" " 'self-insert-command
)
187 (define-key calc-var-name-map
(char-to-string x
)
192 (define-key calc-var-name-map
(char-to-string x
)
196 (defun calcVar-digit ()
198 (if (calc-minibuffer-contains "var-\\'")
199 (if (eq calc-store-opers
0)
202 (self-insert-and-exit))
203 (self-insert-command 1)))
205 (defun calcVar-oper ()
207 (if (and (eq calc-store-opers t
)
208 (calc-minibuffer-contains "var-\\'"))
211 (self-insert-and-exit))
212 (self-insert-command 1)))
214 (defun calc-store-map (&optional oper var
)
217 (let* ((sel-mode nil
)
218 (calc-dollar-values (mapcar 'calc-get-stack-element
219 (nthcdr calc-stack-top calc-stack
)))
221 (oper (or oper
(calc-get-operator "Store Mapping")))
223 (or var
(setq var
(calc-read-var-name (format "Store Mapping %s: "
226 (let ((old (or (calc-var-value var
)
227 (error "No such variable: \"%s\""
228 (calc-var-name var
))))
229 (calc-simplify-mode (if (eq calc-simplify-mode
'none
)
230 'num calc-simplify-mode
))
231 (values (and (> nargs
1)
232 (calc-top-list (1- nargs
) (1+ calc-dollar-used
)))))
233 (message "Working...")
234 (calc-set-command-flag 'clear-message
)
236 (setq old
(math-read-expr old
)))
237 (if (eq (car-safe old
) 'error
)
238 (error "Bad format in variable contents: %s" (nth 2 old
)))
239 (setq values
(if (calc-is-inverse)
240 (append values
(list old
))
241 (append (list old
) values
)))
242 (calc-store-value var
243 (calc-normalize (cons (nth 1 oper
) values
))
245 (+ calc-dollar-used
(1- nargs
))))))))
247 (defun calc-store-exchange (&optional var
)
250 (let ((calc-given-value nil
)
251 (calc-given-value-flag 1)
253 (or var
(setq var
(calc-read-var-name "Exchange with: ")))
255 (let ((value (calc-var-value var
)))
257 (error "No such variable: \"%s\"" (calc-var-name var
)))
258 (if (eq (car-safe value
) 'special-const
)
259 (error "%s is a special constant" var
))
260 (setq top
(or calc-given-value
(calc-top 1)))
261 (calc-store-value var top nil
)
262 (calc-pop-push-record calc-given-value-flag
263 (concat "<>" (calc-var-name var
)) value
))))))
265 (defun calc-unstore (&optional var
)
268 (or var
(setq var
(calc-read-var-name "Unstore: ")))
271 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
272 (eq (car-safe (calc-var-value var
)) 'special-const
)
273 (message "(Note: Built-in definition of %s has been lost)" var
))
274 (if (and (boundp var
) (symbol-value var
))
275 (message "Unstored variable \"%s\"" (calc-var-name var
))
276 (message "Variable \"%s\" remains unstored" (calc-var-name var
)))
278 (calc-refresh-evaltos var
)))))
280 (defun calc-let (&optional var
)
283 (let* ((calc-given-value nil
)
284 (calc-given-value-flag 1)
286 (or var
(setq var
(calc-read-var-name "Let variable: ")))
288 (setq value calc-given-value
290 (setq value
(calc-top 1)
293 (list (cons var value
))
294 (calc-is-assignments value
)))
296 (calc-pop-push-record
297 (1+ calc-given-value-flag
)
298 (concat "=" (calc-var-name (car (car var
))))
299 (let ((saved-val (mapcar (function
301 (and (boundp (car v
))
302 (symbol-value (car v
)))))
307 (set (car (car vv
)) (calc-normalize (cdr (car vv
))))
308 (calc-refresh-evaltos (car (car vv
)))
310 (math-evaluate-expr thing
))
313 (set (car (car var
)) (car saved-val
))
314 (makunbound (car (car var
))))
315 (setq saved-val
(cdr saved-val
)
317 (calc-handle-whys))))))))
319 (defun calc-is-assignments (value)
320 (if (memq (car-safe value
) '(calcFunc-eq calcFunc-assign
))
321 (and (eq (car-safe (nth 1 value
)) 'var
)
322 (list (cons (nth 2 (nth 1 value
)) (nth 2 value
))))
323 (if (eq (car-safe value
) 'vec
)
325 (while (and (setq value
(cdr value
))
326 (memq (car-safe (car value
))
327 '(calcFunc-eq calcFunc-assign
))
328 (eq (car-safe (nth 1 (car value
))) 'var
))
329 (setq vv
(cons (cons (nth 2 (nth 1 (car value
)))
335 (defun calc-recall (&optional var
)
338 (or var
(setq var
(calc-read-var-name "Recall: ")))
340 (let ((value (calc-var-value var
)))
342 (error "No such variable: \"%s\"" (calc-var-name var
)))
344 (setq value
(math-read-expr value
)))
345 (if (eq (car-safe value
) 'error
)
346 (error "Bad format in variable contents: %s" (nth 2 value
)))
347 (setq value
(calc-normalize value
))
348 (let ((calc-full-trail-vectors nil
))
349 (calc-record value
(concat "<" (calc-var-name var
))))
350 (calc-push value
)))))
352 (defun calc-store-quick ()
354 (calc-store (intern (format "var-q%c" last-command-char
))))
356 (defun calc-store-into-quick ()
358 (calc-store-into (intern (format "var-q%c" last-command-char
))))
360 (defun calc-recall-quick ()
362 (calc-recall (intern (format "var-q%c" last-command-char
))))
364 (defun calc-copy-variable (&optional var1 var2
)
367 (or var1
(setq var1
(calc-read-var-name "Copy variable: ")))
369 (let ((value (calc-var-value var1
)))
371 (error "No such variable: \"%s\"" (calc-var-name var
)))
372 (or var2
(setq var2
(calc-read-var-name
373 (format "Copy variable: %s, to: " var1
))))
375 (calc-store-value var2 value
""))))))
377 (defvar calc-last-edited-variable nil
)
378 (defun calc-edit-variable (&optional var
)
381 (or var
(setq var
(calc-read-var-name
382 (if calc-last-edited-variable
383 (format "Edit: (default %s) "
384 (calc-var-name calc-last-edited-variable
))
386 (or var
(setq var calc-last-edited-variable
))
388 (let* ((value (calc-var-value var
)))
389 (if (eq (car-safe value
) 'special-const
)
390 (error "%s is a special constant" var
))
391 (setq calc-last-edited-variable var
)
392 (calc-edit-mode (list 'calc-finish-stack-edit
(list 'quote var
))
394 (concat "Editing " (calc-var-name var
)))
396 (insert (math-format-nice-expr value
(frame-width)) "\n")))))
397 (calc-show-edit-buffer))
399 (defun calc-edit-Decls ()
401 (calc-edit-variable 'var-Decls
))
403 (defun calc-edit-EvalRules ()
405 (calc-edit-variable 'var-EvalRules
))
407 (defun calc-edit-FitRules ()
409 (calc-edit-variable 'var-FitRules
))
411 (defun calc-edit-GenCount ()
413 (calc-edit-variable 'var-GenCount
))
415 (defun calc-edit-Holidays ()
417 (calc-edit-variable 'var-Holidays
))
419 (defun calc-edit-IntegLimit ()
421 (calc-edit-variable 'var-IntegLimit
))
423 (defun calc-edit-LineStyles ()
425 (calc-edit-variable 'var-LineStyles
))
427 (defun calc-edit-PointStyles ()
429 (calc-edit-variable 'var-PointStyles
))
431 (defun calc-edit-PlotRejects ()
433 (calc-edit-variable 'var-PlotRejects
))
435 (defun calc-edit-AlgSimpRules ()
437 (calc-edit-variable 'var-AlgSimpRules
))
439 (defun calc-edit-TimeZone ()
441 (calc-edit-variable 'var-TimeZone
))
443 (defun calc-edit-Units ()
445 (calc-edit-variable 'var-Units
))
447 (defun calc-edit-ExtSimpRules ()
449 (calc-edit-variable 'var-ExtSimpRules
))
451 (defun calc-declare-variable (&optional var
)
454 (or var
(setq var
(calc-read-var-name "Declare: " 0)))
455 (or var
(setq var
'var-All
))
456 (let* (dp decl def row rp
)
457 (or (and (calc-var-value 'var-Decls
)
458 (eq (car-safe var-Decls
) 'vec
))
459 (setq var-Decls
(list 'vec
)))
461 (while (and (setq dp
(cdr dp
))
462 (or (not (eq (car-safe (car dp
)) 'vec
))
463 (/= (length (car dp
)) 3)
465 (setq row
(nth 1 (car dp
))
467 (if (eq (car-safe row
) 'vec
)
470 (and (setq rp
(cdr rp
))
471 (or (not (eq (car-safe (car rp
)) 'var
))
472 (not (eq (nth 2 (car rp
)) var
)))))
474 (if (or (not (eq (car-safe row
) 'var
))
475 (not (eq (nth 2 row
) var
)))
478 (calc-unread-command ?\C-a
)
479 (setq decl
(read-string (format "Declare: %s to be: " var
)
481 (math-format-flat-expr (nth 2 (car dp
)) 0))))
482 (setq decl
(and (string-match "[^ \t]" decl
)
483 (math-read-exprs decl
)))
484 (if (eq (car-safe decl
) 'error
)
485 (error "Bad format in declaration: %s" (nth 2 decl
)))
487 (setq decl
(cons 'vec decl
))
488 (setq decl
(car decl
)))
489 (and (eq (car-safe decl
) 'vec
)
491 (setq decl
(nth 1 decl
)))
492 (calc-record (append '(vec) (list (math-build-var-name var
))
493 (and decl
(list decl
)))
495 (setq var-Decls
(copy-sequence var-Decls
))
496 (if (eq (car-safe row
) 'vec
)
498 (setcdr row
(delq rp
(cdr row
)))
500 (setq var-Decls
(delq (car dp
) var-Decls
))))
501 (setq var-Decls
(delq (car dp
) var-Decls
)))
504 (setq dp
(and (not (eq var
'var-All
)) var-Decls
))
505 (while (and (setq dp
(cdr dp
))
506 (or (not (eq (car-safe (car dp
)) 'vec
))
507 (/= (length (car dp
)) 3)
508 (not (equal (nth 2 (car dp
)) decl
)))))
510 (setcar (cdr (car dp
))
511 (append (if (eq (car-safe (nth 1 (car dp
))) 'vec
)
513 (list 'vec
(nth 1 (car dp
))))
514 (list (math-build-var-name var
))))
515 (setq var-Decls
(append var-Decls
517 (math-build-var-name var
)
519 (calc-refresh-evaltos 'var-Decls
))))
521 (defvar calc-dont-insert-variables
'(var-FitRules var-FactorRules
522 var-CommuteRules var-JumpRules
523 var-DistribRules var-MergeRules
524 var-NegateRules var-InvertRules
526 var-TimeZone var-PlotRejects
527 var-PlotData1 var-PlotData2
528 var-PlotData3 var-PlotData4
529 var-PlotData5 var-PlotData6
532 (defun calc-permanent-variable (&optional var
)
535 (or var
(setq var
(calc-read-var-name "Save variable (default=all): ")))
537 (and var
(or (and (boundp var
) (symbol-value var
))
538 (error "No such variable")))
539 (set-buffer (find-file-noselect (substitute-in-file-name
540 calc-settings-file
)))
542 (calc-insert-permanent-variable var
)
545 (and (string-match "\\`var-" (symbol-name x
))
546 (not (memq x calc-dont-insert-variables
))
548 (not (eq (car-safe (symbol-value x
)) 'special-const
))
549 (calc-insert-permanent-variable x
))))))
554 (defun calc-insert-permanent-variable (var)
555 (goto-char (point-min))
556 (if (search-forward (concat "(setq " (symbol-name var
) " '") nil t
)
558 (setq pos
(point-marker))
560 (if (looking-at ";;; Variable .* stored by Calc on ")
562 (delete-region (match-end 0) (progn (end-of-line) (point)))
563 (insert (current-time-string))))
564 (goto-char (- pos
8 (length (symbol-name var
))))
567 (delete-region pos
(point)))
568 (goto-char (point-max))
569 (insert "\n;;; Variable \""
571 "\" stored by Calc on "
572 (current-time-string)
577 (insert (prin1-to-string (calc-var-value var
)))
580 (defun calc-insert-variables (buf)
581 (interactive "bBuffer in which to save variable values: ")
586 (and (string-match "\\`var-" (symbol-name x
))
587 (not (memq x calc-dont-insert-variables
))
589 (not (eq (car-safe (symbol-value x
)) 'special-const
))
590 (or (not (eq x
'var-Decls
))
591 (not (equal var-Decls
'(vec))))
592 (or (not (eq x
'var-Holidays
))
593 (not (equal var-Holidays
'(vec (var sat var-sat
)
594 (var sun var-sun
)))))
600 (if (memq calc-language
'(nil big
))
603 (math-format-value (symbol-value x
) 100000)))
606 (defun calc-assign (arg)
609 (calc-binary-op ":=" 'calcFunc-assign arg
)))
611 (defun calc-evalto (arg)
614 (calc-unary-op "=>" 'calcFunc-evalto arg
)))
616 (defun calc-subscript (arg)
619 (calc-binary-op "sub" 'calcFunc-subscr arg
)))
621 ;;; calc-store.el ends here