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 ;; Maintainers: D. Goel <deego@gnufans.org>
7 ;; Colin Walters <walters@debian.org>
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is distributed in the hope that it will be useful,
12 ;; but WITHOUT ANY WARRANTY. No author or distributor
13 ;; accepts responsibility to anyone for the consequences of using it
14 ;; or for whether it serves any particular purpose or works at all,
15 ;; unless he says so in writing. Refer to the GNU Emacs General Public
16 ;; License for full details.
18 ;; Everyone is granted permission to copy, modify and redistribute
19 ;; GNU Emacs, but only under the conditions described in the
20 ;; GNU Emacs General Public License. A copy of this license is
21 ;; supposed to have been given to you along with GNU Emacs so you
22 ;; can know your rights and responsibilities. It should be in a
23 ;; file named COPYING. Among other things, the copyright notice
24 ;; and this notice must be preserved on all copies.
30 ;; This file is autoloaded from calc-ext.el.
35 (defun calc-Need-calc-store () nil
)
40 (defvar calc-store-keep nil
)
41 (defun calc-store (&optional var
)
43 (let ((calc-store-keep t
))
44 (calc-store-into var
)))
46 (defvar calc-given-value-flag nil
)
47 (defun calc-store-into (&optional var
)
50 (let ((calc-given-value nil
)
51 (calc-given-value-flag 1))
52 (or var
(setq var
(calc-read-var-name "Store: " t
)))
54 (let ((found (assq var
'( ( + . calc-store-plus
)
55 ( - . calc-store-minus
)
56 ( * . calc-store-times
)
57 ( / . calc-store-div
)
58 ( ^ . calc-store-power
)
59 ( | . calc-store-concat
) ))))
62 (calc-store-value var
(or calc-given-value
(calc-top 1))
63 "" calc-given-value-flag
)
64 (message "Stored to variable \"%s\"" (calc-var-name var
))))
65 (setq var
(calc-is-assignments (calc-top 1)))
68 (calc-store-value (car (car var
)) (cdr (car var
))
69 (if (not (cdr var
)) "")
70 (if (not (cdr var
)) 1))
71 (setq var
(cdr var
))))))))
73 (defun calc-store-plus (&optional var
)
75 (calc-store-binary var
"+" '+))
77 (defun calc-store-minus (&optional var
)
79 (calc-store-binary var
"-" '-
))
81 (defun calc-store-times (&optional var
)
83 (calc-store-binary var
"*" '*))
85 (defun calc-store-div (&optional var
)
87 (calc-store-binary var
"/" '/))
89 (defun calc-store-power (&optional var
)
91 (calc-store-binary var
"^" '^
))
93 (defun calc-store-concat (&optional var
)
95 (calc-store-binary var
"|" '|
))
97 (defun calc-store-neg (n &optional var
)
99 (calc-store-binary var
"n" '/ (- n
)))
101 (defun calc-store-inv (n &optional var
)
103 (calc-store-binary var
"&" '^
(- n
)))
105 (defun calc-store-incr (n &optional var
)
107 (calc-store-binary var
"n" '-
(- n
)))
109 (defun calc-store-decr (n &optional var
)
111 (calc-store-binary var
"n" '- n
))
113 (defun calc-store-value (var value tag
&optional pop
)
115 (let ((old (calc-var-value var
)))
117 (if pop
(or calc-store-keep
(calc-pop-stack pop
)))
118 (calc-record-undo (list 'store
(symbol-name var
) old
))
120 (let ((calc-full-trail-vectors nil
))
121 (calc-record value
(format ">%s%s" tag
(calc-var-name var
)))))
122 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
123 (eq (car-safe old
) 'special-const
)
124 (message "(Note: Built-in definition of %s has been lost)" var
))
125 (and (memq var
'(var-inf var-uinf var-nan
))
127 (message "(Note: %s has built-in meanings which may interfere)"
129 (calc-refresh-evaltos var
))))
131 (defun calc-var-name (var)
132 (if (symbolp var
) (setq var
(symbol-name var
)))
133 (if (string-match "\\`var-." var
)
137 (defun calc-store-binary (var tag func
&optional val
)
139 (let ((calc-simplify-mode (if (eq calc-simplify-mode
'none
)
140 'num calc-simplify-mode
))
141 (value (or val
(calc-top 1))))
142 (or var
(setq var
(calc-read-var-name (format "Store %s: " tag
))))
144 (let ((old (calc-var-value var
)))
146 (error "No such variable: \"%s\"" (calc-var-name var
)))
148 (setq old
(math-read-expr old
)))
149 (if (eq (car-safe old
) 'error
)
150 (error "Bad format in variable contents: %s" (nth 2 old
)))
151 (calc-store-value var
152 (calc-normalize (if (calc-is-inverse)
153 (list func value old
)
154 (list func old value
)))
155 tag
(and (not val
) 1))
156 (message "Stored to variable \"%s\"" (calc-var-name var
)))))))
158 (defun calc-read-var-name (prompt &optional calc-store-opers
)
159 (setq calc-given-value nil
160 calc-aborted-prefix nil
)
161 (let ((var (let ((minibuffer-completion-table obarray
)
162 (minibuffer-completion-predicate 'boundp
)
163 (minibuffer-completion-confirm t
))
164 (read-from-minibuffer prompt
"var-" calc-var-name-map nil
))))
165 (setq calc-aborted-prefix
"")
166 (and (not (equal var
""))
167 (not (equal var
"var-"))
168 (if (string-match "\\`\\([-a-zA-Z0-9]+\\) *:?=" var
)
169 (if (null calc-given-value-flag
)
170 (error "Assignment is not allowed in this command")
171 (let ((svar (intern (substring var
0 (match-end 1)))))
172 (setq calc-given-value-flag
0
173 calc-given-value
(math-read-expr
174 (substring var
(match-end 0))))
175 (if (eq (car-safe calc-given-value
) 'error
)
176 (error "Bad format: %s" (nth 2 calc-given-value
)))
177 (setq calc-given-value
(math-evaluate-expr calc-given-value
))
181 (defvar calc-var-name-map nil
"Keymap for reading Calc variable names.")
182 (if calc-var-name-map
184 (setq calc-var-name-map
(copy-keymap minibuffer-local-completion-map
))
185 (define-key calc-var-name-map
" " 'self-insert-command
)
188 (define-key calc-var-name-map
(char-to-string x
)
193 (define-key calc-var-name-map
(char-to-string x
)
197 (defun calcVar-digit ()
199 (if (calc-minibuffer-contains "var-\\'")
200 (if (eq calc-store-opers
0)
203 (self-insert-and-exit))
204 (self-insert-command 1)))
206 (defun calcVar-oper ()
208 (if (and (eq calc-store-opers t
)
209 (calc-minibuffer-contains "var-\\'"))
212 (self-insert-and-exit))
213 (self-insert-command 1)))
215 (defun calc-store-map (&optional oper var
)
218 (let* ((sel-mode nil
)
219 (calc-dollar-values (mapcar 'calc-get-stack-element
220 (nthcdr calc-stack-top calc-stack
)))
222 (oper (or oper
(calc-get-operator "Store Mapping")))
224 (or var
(setq var
(calc-read-var-name (format "Store Mapping %s: "
227 (let ((old (or (calc-var-value var
)
228 (error "No such variable: \"%s\""
229 (calc-var-name var
))))
230 (calc-simplify-mode (if (eq calc-simplify-mode
'none
)
231 'num calc-simplify-mode
))
232 (values (and (> nargs
1)
233 (calc-top-list (1- nargs
) (1+ calc-dollar-used
)))))
234 (message "Working...")
235 (calc-set-command-flag 'clear-message
)
237 (setq old
(math-read-expr old
)))
238 (if (eq (car-safe old
) 'error
)
239 (error "Bad format in variable contents: %s" (nth 2 old
)))
240 (setq values
(if (calc-is-inverse)
241 (append values
(list old
))
242 (append (list old
) values
)))
243 (calc-store-value var
244 (calc-normalize (cons (nth 1 oper
) values
))
246 (+ calc-dollar-used
(1- nargs
))))))))
248 (defun calc-store-exchange (&optional var
)
251 (let ((calc-given-value nil
)
252 (calc-given-value-flag 1)
254 (or var
(setq var
(calc-read-var-name "Exchange with: ")))
256 (let ((value (calc-var-value var
)))
258 (error "No such variable: \"%s\"" (calc-var-name var
)))
259 (if (eq (car-safe value
) 'special-const
)
260 (error "%s is a special constant" var
))
261 (setq top
(or calc-given-value
(calc-top 1)))
262 (calc-store-value var top nil
)
263 (calc-pop-push-record calc-given-value-flag
264 (concat "<>" (calc-var-name var
)) value
))))))
266 (defun calc-unstore (&optional var
)
269 (or var
(setq var
(calc-read-var-name "Unstore: ")))
272 (and (memq var
'(var-e var-i var-pi var-phi var-gamma
))
273 (eq (car-safe (calc-var-value var
)) 'special-const
)
274 (message "(Note: Built-in definition of %s has been lost)" var
))
275 (if (and (boundp var
) (symbol-value var
))
276 (message "Unstored variable \"%s\"" (calc-var-name var
))
277 (message "Variable \"%s\" remains unstored" (calc-var-name var
)))
279 (calc-refresh-evaltos var
)))))
281 (defun calc-let (&optional var
)
284 (let* ((calc-given-value nil
)
285 (calc-given-value-flag 1)
287 (or var
(setq var
(calc-read-var-name "Let variable: ")))
289 (setq value calc-given-value
291 (setq value
(calc-top 1)
294 (list (cons var value
))
295 (calc-is-assignments value
)))
297 (calc-pop-push-record
298 (1+ calc-given-value-flag
)
299 (concat "=" (calc-var-name (car (car var
))))
300 (let ((saved-val (mapcar (function
302 (and (boundp (car v
))
303 (symbol-value (car v
)))))
308 (set (car (car vv
)) (calc-normalize (cdr (car vv
))))
309 (calc-refresh-evaltos (car (car vv
)))
311 (math-evaluate-expr thing
))
314 (set (car (car var
)) (car saved-val
))
315 (makunbound (car (car var
))))
316 (setq saved-val
(cdr saved-val
)
318 (calc-handle-whys))))))))
320 (defun calc-is-assignments (value)
321 (if (memq (car-safe value
) '(calcFunc-eq calcFunc-assign
))
322 (and (eq (car-safe (nth 1 value
)) 'var
)
323 (list (cons (nth 2 (nth 1 value
)) (nth 2 value
))))
324 (if (eq (car-safe value
) 'vec
)
326 (while (and (setq value
(cdr value
))
327 (memq (car-safe (car value
))
328 '(calcFunc-eq calcFunc-assign
))
329 (eq (car-safe (nth 1 (car value
))) 'var
))
330 (setq vv
(cons (cons (nth 2 (nth 1 (car value
)))
336 (defun calc-recall (&optional var
)
339 (or var
(setq var
(calc-read-var-name "Recall: ")))
341 (let ((value (calc-var-value var
)))
343 (error "No such variable: \"%s\"" (calc-var-name var
)))
345 (setq value
(math-read-expr value
)))
346 (if (eq (car-safe value
) 'error
)
347 (error "Bad format in variable contents: %s" (nth 2 value
)))
348 (setq value
(calc-normalize value
))
349 (let ((calc-full-trail-vectors nil
))
350 (calc-record value
(concat "<" (calc-var-name var
))))
351 (calc-push value
)))))
353 (defun calc-store-quick ()
355 (calc-store (intern (format "var-q%c" last-command-char
))))
357 (defun calc-store-into-quick ()
359 (calc-store-into (intern (format "var-q%c" last-command-char
))))
361 (defun calc-recall-quick ()
363 (calc-recall (intern (format "var-q%c" last-command-char
))))
365 (defun calc-copy-variable (&optional var1 var2
)
368 (or var1
(setq var1
(calc-read-var-name "Copy variable: ")))
370 (let ((value (calc-var-value var1
)))
372 (error "No such variable: \"%s\"" (calc-var-name var
)))
373 (or var2
(setq var2
(calc-read-var-name
374 (format "Copy variable: %s, to: " var1
))))
376 (calc-store-value var2 value
""))))))
378 (defvar calc-last-edited-variable nil
)
379 (defun calc-edit-variable (&optional var
)
382 (or var
(setq var
(calc-read-var-name
383 (if calc-last-edited-variable
384 (format "Edit: (default %s) "
385 (calc-var-name calc-last-edited-variable
))
387 (or var
(setq var calc-last-edited-variable
))
389 (let* ((value (calc-var-value var
)))
390 (if (eq (car-safe value
) 'special-const
)
391 (error "%s is a special constant" var
))
392 (setq calc-last-edited-variable var
)
393 (calc-edit-mode (list 'calc-finish-stack-edit
(list 'quote var
))
395 (concat "Editing " (calc-var-name var
)))
397 (insert (math-format-nice-expr value
(frame-width)) "\n")))))
398 (calc-show-edit-buffer))
400 (defun calc-edit-Decls ()
402 (calc-edit-variable 'var-Decls
))
404 (defun calc-edit-EvalRules ()
406 (calc-edit-variable 'var-EvalRules
))
408 (defun calc-edit-FitRules ()
410 (calc-edit-variable 'var-FitRules
))
412 (defun calc-edit-GenCount ()
414 (calc-edit-variable 'var-GenCount
))
416 (defun calc-edit-Holidays ()
418 (calc-edit-variable 'var-Holidays
))
420 (defun calc-edit-IntegLimit ()
422 (calc-edit-variable 'var-IntegLimit
))
424 (defun calc-edit-LineStyles ()
426 (calc-edit-variable 'var-LineStyles
))
428 (defun calc-edit-PointStyles ()
430 (calc-edit-variable 'var-PointStyles
))
432 (defun calc-edit-PlotRejects ()
434 (calc-edit-variable 'var-PlotRejects
))
436 (defun calc-edit-AlgSimpRules ()
438 (calc-edit-variable 'var-AlgSimpRules
))
440 (defun calc-edit-TimeZone ()
442 (calc-edit-variable 'var-TimeZone
))
444 (defun calc-edit-Units ()
446 (calc-edit-variable 'var-Units
))
448 (defun calc-edit-ExtSimpRules ()
450 (calc-edit-variable 'var-ExtSimpRules
))
452 (defun calc-declare-variable (&optional var
)
455 (or var
(setq var
(calc-read-var-name "Declare: " 0)))
456 (or var
(setq var
'var-All
))
457 (let* (dp decl def row rp
)
458 (or (and (calc-var-value 'var-Decls
)
459 (eq (car-safe var-Decls
) 'vec
))
460 (setq var-Decls
(list 'vec
)))
462 (while (and (setq dp
(cdr dp
))
463 (or (not (eq (car-safe (car dp
)) 'vec
))
464 (/= (length (car dp
)) 3)
466 (setq row
(nth 1 (car dp
))
468 (if (eq (car-safe row
) 'vec
)
471 (and (setq rp
(cdr rp
))
472 (or (not (eq (car-safe (car rp
)) 'var
))
473 (not (eq (nth 2 (car rp
)) var
)))))
475 (if (or (not (eq (car-safe row
) 'var
))
476 (not (eq (nth 2 row
) var
)))
479 (calc-unread-command ?\C-a
)
480 (setq decl
(read-string (format "Declare: %s to be: " var
)
482 (math-format-flat-expr (nth 2 (car dp
)) 0))))
483 (setq decl
(and (string-match "[^ \t]" decl
)
484 (math-read-exprs decl
)))
485 (if (eq (car-safe decl
) 'error
)
486 (error "Bad format in declaration: %s" (nth 2 decl
)))
488 (setq decl
(cons 'vec decl
))
489 (setq decl
(car decl
)))
490 (and (eq (car-safe decl
) 'vec
)
492 (setq decl
(nth 1 decl
)))
493 (calc-record (append '(vec) (list (math-build-var-name var
))
494 (and decl
(list decl
)))
496 (setq var-Decls
(copy-sequence var-Decls
))
497 (if (eq (car-safe row
) 'vec
)
499 (setcdr row
(delq rp
(cdr row
)))
501 (setq var-Decls
(delq (car dp
) var-Decls
))))
502 (setq var-Decls
(delq (car dp
) var-Decls
)))
505 (setq dp
(and (not (eq var
'var-All
)) var-Decls
))
506 (while (and (setq dp
(cdr dp
))
507 (or (not (eq (car-safe (car dp
)) 'vec
))
508 (/= (length (car dp
)) 3)
509 (not (equal (nth 2 (car dp
)) decl
)))))
511 (setcar (cdr (car dp
))
512 (append (if (eq (car-safe (nth 1 (car dp
))) 'vec
)
514 (list 'vec
(nth 1 (car dp
))))
515 (list (math-build-var-name var
))))
516 (setq var-Decls
(append var-Decls
518 (math-build-var-name var
)
520 (calc-refresh-evaltos 'var-Decls
))))
522 (defvar calc-dont-insert-variables
'(var-FitRules var-FactorRules
523 var-CommuteRules var-JumpRules
524 var-DistribRules var-MergeRules
525 var-NegateRules var-InvertRules
527 var-TimeZone var-PlotRejects
528 var-PlotData1 var-PlotData2
529 var-PlotData3 var-PlotData4
530 var-PlotData5 var-PlotData6
533 (defun calc-permanent-variable (&optional var
)
536 (or var
(setq var
(calc-read-var-name "Save variable (default=all): ")))
538 (and var
(or (and (boundp var
) (symbol-value var
))
539 (error "No such variable")))
540 (set-buffer (find-file-noselect (substitute-in-file-name
541 calc-settings-file
)))
543 (calc-insert-permanent-variable var
)
546 (and (string-match "\\`var-" (symbol-name x
))
547 (not (memq x calc-dont-insert-variables
))
549 (not (eq (car-safe (symbol-value x
)) 'special-const
))
550 (calc-insert-permanent-variable x
))))))
555 (defun calc-insert-permanent-variable (var)
556 (goto-char (point-min))
557 (if (search-forward (concat "(setq " (symbol-name var
) " '") nil t
)
559 (setq pos
(point-marker))
561 (if (looking-at ";;; Variable .* stored by Calc on ")
563 (delete-region (match-end 0) (progn (end-of-line) (point)))
564 (insert (current-time-string))))
565 (goto-char (- pos
8 (length (symbol-name var
))))
568 (delete-region pos
(point)))
569 (goto-char (point-max))
570 (insert "\n;;; Variable \""
572 "\" stored by Calc on "
573 (current-time-string)
578 (insert (prin1-to-string (calc-var-value var
)))
581 (defun calc-insert-variables (buf)
582 (interactive "bBuffer in which to save variable values: ")
587 (and (string-match "\\`var-" (symbol-name x
))
588 (not (memq x calc-dont-insert-variables
))
590 (not (eq (car-safe (symbol-value x
)) 'special-const
))
591 (or (not (eq x
'var-Decls
))
592 (not (equal var-Decls
'(vec))))
593 (or (not (eq x
'var-Holidays
))
594 (not (equal var-Holidays
'(vec (var sat var-sat
)
595 (var sun var-sun
)))))
601 (if (memq calc-language
'(nil big
))
604 (math-format-value (symbol-value x
) 100000)))
607 (defun calc-assign (arg)
610 (calc-binary-op ":=" 'calcFunc-assign arg
)))
612 (defun calc-evalto (arg)
615 (calc-unary-op "=>" 'calcFunc-evalto arg
)))
617 (defun calc-subscript (arg)
620 (calc-binary-op "sub" 'calcFunc-subscr arg
)))
622 ;;; calc-store.el ends here