home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-10-31 | 55.3 KB | 1,905 lines |
- Newsgroups: comp.sources.misc
- From: daveg@synaptics.com (David Gillespie)
- Subject: v24i072: gnucalc - GNU Emacs Calculator, v2.00, Part24/56
- Message-ID: <1991Oct31.072739.18175@sparky.imd.sterling.com>
- X-Md4-Signature: 73e94080579af1b29e16619cb5083d9d
- Date: Thu, 31 Oct 1991 07:27:39 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: daveg@synaptics.com (David Gillespie)
- Posting-number: Volume 24, Issue 72
- Archive-name: gnucalc/part24
- Environment: Emacs
- Supersedes: gmcalc: Volume 13, Issue 27-45
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file calc-prog.el continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 24; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping calc-prog.el'
- else
- echo 'x - continuing file calc-prog.el'
- sed 's/^X//' << 'SHAR_EOF' >> 'calc-prog.el' &&
- X (assq (downcase key) (calc-user-key-map))
- X (error "No command defined for that key")))
- X (cmd (cdr def)))
- X (if (symbolp cmd)
- X (setq cmd (symbol-function cmd)))
- X (cond ((stringp cmd)
- X (message "Keyboard macro: %s" cmd))
- X (t (let* ((func (calc-stack-command-p cmd))
- X (defn (and func
- X (symbolp func)
- X (get func 'calc-user-defn))))
- X (if defn
- X (progn
- X (and (calc-valid-formula-func func)
- X (setq defn (append '(calcFunc-lambda)
- X (mapcar 'math-build-var-name
- X (nth 1 (symbol-function
- X func)))
- X (list defn))))
- X (calc-enter-result 0 "gdef" defn))
- X (error "That command is not defined by a formula")))))))
- )
- X
- X
- (defun calc-user-define-permanent ()
- X (interactive)
- X (calc-wrapper
- X (message "Record in %s the command: z-" calc-settings-file)
- X (let* ((key (read-char))
- X (def (or (assq key (calc-user-key-map))
- X (assq (upcase key) (calc-user-key-map))
- X (assq (downcase key) (calc-user-key-map))
- X (and (eq key ?\')
- X (cons nil
- X (intern (completing-read
- X (format "Record in %s the function: "
- X calc-settings-file)
- X obarray 'fboundp nil "calcFunc-"))))
- X (error "No command defined for that key"))))
- X (set-buffer (find-file-noselect (substitute-in-file-name
- X calc-settings-file)))
- X (goto-char (point-max))
- X (let* ((cmd (cdr def))
- X (fcmd (and cmd (symbolp cmd) (symbol-function cmd)))
- X (func nil)
- X (pt (point))
- X (fill-column 70)
- X (fill-prefix nil)
- X str q-ok)
- X (insert "\n;;; Definition stored by Calc on " (current-time-string)
- X "\n(put 'calc-define '"
- X (if (symbolp cmd) (symbol-name cmd) (format "key%d" key))
- X " '(progn\n")
- X (if (and fcmd
- X (eq (car-safe fcmd) 'lambda)
- X (get cmd 'calc-user-defn))
- X (let ((pt (point)))
- X (and (eq (car-safe (nth 3 fcmd)) 'calc-execute-kbd-macro)
- X (vectorp (nth 1 (nth 3 fcmd)))
- X (progn (and (fboundp 'edit-kbd-macro)
- X (edit-kbd-macro nil))
- X (fboundp 'MacEdit-parse-keys))
- X (setq q-ok t)
- X (aset (nth 1 (nth 3 fcmd)) 1 nil))
- X (insert (setq str (prin1-to-string
- X (cons 'defun (cons cmd (cdr fcmd)))))
- X "\n")
- X (or (and (string-match "\"" str) (not q-ok))
- X (fill-region pt (point)))
- X (indent-rigidly pt (point) 2)
- X (delete-region pt (1+ pt))
- X (insert " (put '" (symbol-name cmd)
- X " 'calc-user-defn '"
- X (prin1-to-string (get cmd 'calc-user-defn))
- X ")\n")
- X (setq func (calc-stack-command-p cmd))
- X (let ((ffunc (and func (symbolp func) (symbol-function func)))
- X (pt (point)))
- X (and ffunc
- X (eq (car-safe ffunc) 'lambda)
- X (get func 'calc-user-defn)
- X (progn
- X (insert (setq str (prin1-to-string
- X (cons 'defun (cons func
- X (cdr ffunc)))))
- X "\n")
- X (or (and (string-match "\"" str) (not q-ok))
- X (fill-region pt (point)))
- X (indent-rigidly pt (point) 2)
- X (delete-region pt (1+ pt))
- X (setq pt (point))
- X (insert "(put '" (symbol-name func)
- X " 'calc-user-defn '"
- X (prin1-to-string (get func 'calc-user-defn))
- X ")\n")
- X (fill-region pt (point))
- X (indent-rigidly pt (point) 2)
- X (delete-region pt (1+ pt))))))
- X (and (stringp fcmd)
- X (insert " (fset '" (prin1-to-string cmd)
- X " " (prin1-to-string fcmd) ")\n")))
- X (or func (setq func (and cmd (symbolp cmd) (fboundp cmd) cmd)))
- X (if (get func 'math-compose-forms)
- X (let ((pt (point)))
- X (insert "(put '" (symbol-name cmd)
- X " 'math-compose-forms '"
- X (prin1-to-string (get func 'math-compose-forms))
- X ")\n")
- X (fill-region pt (point))
- X (indent-rigidly pt (point) 2)
- X (delete-region pt (1+ pt))))
- X (if (car def)
- X (insert " (define-key calc-mode-map "
- X (prin1-to-string (concat "z" (char-to-string key)))
- X " '"
- X (prin1-to-string cmd)
- X ")\n")))
- X (insert "))\n")
- X (save-buffer)))
- )
- X
- (defun calc-stack-command-p (cmd)
- X (if (and cmd (symbolp cmd))
- X (and (fboundp cmd)
- X (calc-stack-command-p (symbol-function cmd)))
- X (and (consp cmd)
- X (eq (car cmd) 'lambda)
- X (setq cmd (or (assq 'calc-wrapper cmd)
- X (assq 'calc-slow-wrapper cmd)))
- X (setq cmd (assq 'calc-enter-result cmd))
- X (memq (car (nth 3 cmd)) '(cons list))
- X (eq (car (nth 1 (nth 3 cmd))) 'quote)
- X (nth 1 (nth 1 (nth 3 cmd)))))
- )
- X
- X
- (defun calc-call-last-kbd-macro (arg)
- X (interactive "P")
- X (and defining-kbd-macro
- X (error "Can't execute anonymous macro while defining one"))
- X (or last-kbd-macro
- X (error "No kbd macro has been defined"))
- X (calc-execute-kbd-macro last-kbd-macro arg)
- )
- X
- (defun calc-execute-kbd-macro (mac arg &rest prefix)
- X (if (vectorp mac)
- X (setq mac (or (aref mac 1)
- X (aset mac 1 (progn (and (fboundp 'edit-kbd-macro)
- X (edit-kbd-macro nil))
- X (MacEdit-parse-keys (aref mac 0)))))))
- X (if (< (prefix-numeric-value arg) 0)
- X (execute-kbd-macro mac (- (prefix-numeric-value arg)))
- X (if calc-executing-macro
- X (execute-kbd-macro mac arg)
- X (calc-slow-wrapper
- X (let ((old-stack-whole (copy-sequence calc-stack))
- X (old-stack-top calc-stack-top)
- X (old-buffer-size (buffer-size))
- X (old-refresh-count calc-refresh-count))
- X (unwind-protect
- X (let ((calc-executing-macro mac))
- X (execute-kbd-macro mac arg))
- X (calc-select-buffer)
- X (let ((new-stack (reverse calc-stack))
- X (old-stack (reverse old-stack-whole)))
- X (while (and new-stack old-stack
- X (equal (car new-stack) (car old-stack)))
- X (setq new-stack (cdr new-stack)
- X old-stack (cdr old-stack)))
- X (or (equal prefix '(nil))
- X (calc-record-list (if (> (length new-stack) 1)
- X (mapcar 'car new-stack)
- X '(""))
- X (or (car prefix) "kmac")))
- X (calc-record-undo (list 'set 'saved-stack-top old-stack-top))
- X (and old-stack
- X (calc-record-undo (list 'pop 1 (mapcar 'car old-stack))))
- X (let ((calc-stack old-stack-whole)
- X (calc-stack-top 0))
- X (calc-cursor-stack-index (length old-stack)))
- X (if (and (= old-buffer-size (buffer-size))
- X (= old-refresh-count calc-refresh-count))
- X (let ((buffer-read-only nil))
- X (delete-region (point) (point-max))
- X (while new-stack
- X (calc-record-undo (list 'push 1))
- X (insert (math-format-stack-value (car new-stack)) "\n")
- X (setq new-stack (cdr new-stack)))
- X (calc-renumber-stack))
- X (while new-stack
- X (calc-record-undo (list 'push 1))
- X (setq new-stack (cdr new-stack)))
- X (calc-refresh))
- X (calc-record-undo (list 'set 'saved-stack-top 0))))))))
- )
- X
- (defun calc-push-list-in-macro (vals m sels)
- X (let ((entry (list (car vals) 1 (car sels)))
- X (mm (+ (or m 1) calc-stack-top)))
- X (if (> mm 1)
- X (setcdr (nthcdr (- mm 2) calc-stack)
- X (cons entry (nthcdr (1- mm) calc-stack)))
- X (setq calc-stack (cons entry calc-stack))))
- )
- X
- (defun calc-pop-stack-in-macro (n mm)
- X (if (> mm 1)
- X (setcdr (nthcdr (- mm 2) calc-stack)
- X (nthcdr (+ n mm -1) calc-stack))
- X (setq calc-stack (nthcdr n calc-stack)))
- )
- X
- X
- (defun calc-kbd-if ()
- X (interactive)
- X (calc-wrapper
- X (let ((cond (calc-top-n 1)))
- X (calc-pop-stack 1)
- X (if (math-is-true cond)
- X (if defining-kbd-macro
- X (message "If true..."))
- X (if defining-kbd-macro
- X (message "Condition is false; skipping to Z: or Z] ..."))
- X (calc-kbd-skip-to-else-if t))))
- )
- X
- (defun calc-kbd-else-if ()
- X (interactive)
- X (calc-kbd-if)
- )
- X
- (defun calc-kbd-skip-to-else-if (else-okay)
- X (let ((count 0)
- X ch)
- X (while (>= count 0)
- X (setq ch (read-char))
- X (if (= ch -1)
- X (error "Unterminated Z[ in keyboard macro"))
- X (if (= ch ?Z)
- X (progn
- X (setq ch (read-char))
- X (cond ((= ch ?\[)
- X (setq count (1+ count)))
- X ((= ch ?\])
- X (setq count (1- count)))
- X ((= ch ?\:)
- X (and (= count 0)
- X else-okay
- X (setq count -1)))
- X ((eq ch 7)
- X (keyboard-quit))))))
- X (and defining-kbd-macro
- X (if (= ch ?\:)
- X (message "Else...")
- X (message "End-if..."))))
- )
- X
- (defun calc-kbd-end-if ()
- X (interactive)
- X (if defining-kbd-macro
- X (message "End-if..."))
- )
- X
- (defun calc-kbd-else ()
- X (interactive)
- X (if defining-kbd-macro
- X (message "Else; skipping to Z] ..."))
- X (calc-kbd-skip-to-else-if nil)
- )
- X
- X
- (defun calc-kbd-repeat ()
- X (interactive)
- X (let (count)
- X (calc-wrapper
- X (setq count (math-trunc (calc-top-n 1)))
- X (or (Math-integerp count)
- X (error "Count must be an integer"))
- X (if (Math-integer-negp count)
- X (setq count 0))
- X (or (integerp count)
- X (setq count 1000000))
- X (calc-pop-stack 1))
- X (calc-kbd-loop count))
- )
- X
- (defun calc-kbd-for (dir)
- X (interactive "P")
- X (let (init final)
- X (calc-wrapper
- X (setq init (calc-top-n 2)
- X final (calc-top-n 1))
- X (or (and (math-anglep init) (math-anglep final))
- X (error "Initial and final values must be real numbers"))
- X (calc-pop-stack 2))
- X (calc-kbd-loop nil init final (and dir (prefix-numeric-value dir))))
- )
- X
- (defun calc-kbd-loop (rpt-count &optional initial final dir)
- X (interactive "P")
- X (setq rpt-count (if rpt-count (prefix-numeric-value rpt-count) 1000000))
- X (let* ((count 0)
- X (parts nil)
- X (body "")
- X (open last-command-char)
- X (counter initial)
- X ch)
- X (or executing-macro
- X (message "Reading loop body..."))
- X (while (>= count 0)
- X (setq ch (read-char))
- X (if (= ch -1)
- X (error "Unterminated Z%c in keyboard macro" open))
- X (if (= ch ?Z)
- X (progn
- X (setq ch (read-char)
- X body (concat body "Z" (char-to-string ch)))
- X (cond ((memq ch '(?\< ?\( ?\{))
- X (setq count (1+ count)))
- X ((memq ch '(?\> ?\) ?\}))
- X (setq count (1- count)))
- X ((and (= ch ?/)
- X (= count 0))
- X (setq parts (nconc parts (list (substring body 0 -2)))
- X body ""))
- X ((eq ch 7)
- X (keyboard-quit))))
- X (setq body (concat body (char-to-string ch)))))
- X (if (/= ch (cdr (assq open '( (?\< . ?\>) (?\( . ?\)) (?\{ . ?\}) ))))
- X (error "Mismatched Z%c and Z%c in keyboard macro" open ch))
- X (or executing-macro
- X (message "Looping..."))
- X (setq body (substring body 0 -2))
- X (and (not executing-macro)
- X (= rpt-count 1000000)
- X (null parts)
- X (null counter)
- X (progn
- X (message "Warning: Infinite loop! Not executing.")
- X (setq rpt-count 0)))
- X (or (not initial) dir
- X (setq dir (math-compare final initial)))
- X (calc-wrapper
- X (while (> rpt-count 0)
- X (let ((part parts))
- X (if counter
- X (if (cond ((eq dir 0) (Math-equal final counter))
- X ((eq dir 1) (Math-lessp final counter))
- X ((eq dir -1) (Math-lessp counter final)))
- X (setq rpt-count 0)
- X (calc-push counter)))
- X (while (and part (> rpt-count 0))
- X (execute-kbd-macro (car part))
- X (if (math-is-true (calc-top-n 1))
- X (setq rpt-count 0)
- X (setq part (cdr part)))
- X (calc-pop-stack 1))
- X (if (> rpt-count 0)
- X (progn
- X (execute-kbd-macro body)
- X (if counter
- X (let ((step (calc-top-n 1)))
- X (calc-pop-stack 1)
- X (setq counter (calcFunc-add counter step)))
- X (setq rpt-count (1- rpt-count))))))))
- X (or executing-macro
- X (message "Looping...done")))
- )
- X
- (defun calc-kbd-end-repeat ()
- X (interactive)
- X (error "Unbalanced Z> in keyboard macro")
- )
- X
- (defun calc-kbd-end-for ()
- X (interactive)
- X (error "Unbalanced Z) in keyboard macro")
- )
- X
- (defun calc-kbd-end-loop ()
- X (interactive)
- X (error "Unbalanced Z} in keyboard macro")
- )
- X
- (defun calc-kbd-break ()
- X (interactive)
- X (calc-wrapper
- X (let ((cond (calc-top-n 1)))
- X (calc-pop-stack 1)
- X (if (math-is-true cond)
- X (error "Keyboard macro aborted."))))
- )
- X
- X
- (defun calc-kbd-push (arg)
- X (interactive "P")
- X (calc-wrapper
- X (let* ((defs (and arg (> (prefix-numeric-value arg) 0)))
- X (var-q0 (and (boundp 'var-q0) var-q0))
- X (var-q1 (and (boundp 'var-q1) var-q1))
- X (var-q2 (and (boundp 'var-q2) var-q2))
- X (var-q3 (and (boundp 'var-q3) var-q3))
- X (var-q4 (and (boundp 'var-q4) var-q4))
- X (var-q5 (and (boundp 'var-q5) var-q5))
- X (var-q6 (and (boundp 'var-q6) var-q6))
- X (var-q7 (and (boundp 'var-q7) var-q7))
- X (var-q8 (and (boundp 'var-q8) var-q8))
- X (var-q9 (and (boundp 'var-q9) var-q9))
- X (calc-internal-prec (if defs 12 calc-internal-prec))
- X (calc-word-size (if defs 32 calc-word-size))
- X (calc-angle-mode (if defs 'deg calc-angle-mode))
- X (calc-simplify-mode (if defs nil calc-simplify-mode))
- X (calc-algebraic-mode (if arg nil calc-algebraic-mode))
- X (calc-incomplete-algebraic-mode (if arg nil
- X calc-incomplete-algebraic-mode))
- X (calc-symbolic-mode (if defs nil calc-symbolic-mode))
- X (calc-matrix-mode (if defs nil calc-matrix-mode))
- X (calc-prefer-frac (if defs nil calc-prefer-frac))
- X (calc-complex-mode (if defs nil calc-complex-mode))
- X (calc-infinite-mode (if defs nil calc-infinite-mode))
- X (count 0)
- X (body "")
- X ch)
- X (if (or executing-macro defining-kbd-macro)
- X (progn
- X (if defining-kbd-macro
- X (message "Reading body..."))
- X (while (>= count 0)
- X (setq ch (read-char))
- X (if (= ch -1)
- X (error "Unterminated Z` in keyboard macro"))
- X (if (= ch ?Z)
- X (progn
- X (setq ch (read-char)
- X body (concat body "Z" (char-to-string ch)))
- X (cond ((eq ch ?\`)
- X (setq count (1+ count)))
- X ((eq ch ?\')
- X (setq count (1- count)))
- X ((eq ch 7)
- X (keyboard-quit))))
- X (setq body (concat body (char-to-string ch)))))
- X (if defining-kbd-macro
- X (message "Reading body...done"))
- X (let ((calc-kbd-push-level 0))
- X (execute-kbd-macro (substring body 0 -2))))
- X (let ((calc-kbd-push-level (1+ calc-kbd-push-level)))
- X (message "Saving modes; type Z' to restore")
- X (recursive-edit)))))
- )
- (setq calc-kbd-push-level 0)
- X
- (defun calc-kbd-pop ()
- X (interactive)
- X (if (> calc-kbd-push-level 0)
- X (progn
- X (message "Mode settings restored")
- X (exit-recursive-edit))
- X (error "Unbalanced Z' in keyboard macro"))
- )
- X
- X
- (defun calc-kbd-report (msg)
- X (interactive "sMessage: ")
- X (calc-wrapper
- X (let ((executing-macro nil)
- X (defining-kbd-macro nil))
- X (math-working msg (calc-top-n 1))))
- )
- X
- (defun calc-kbd-query (msg)
- X (interactive "sPrompt: ")
- X (calc-wrapper
- X (let ((executing-macro nil)
- X (defining-kbd-macro nil))
- X (calc-alg-entry nil (and (not (equal msg "")) msg))))
- )
- X
- X
- X
- X
- X
- X
- X
- ;;;; Logical operations.
- X
- (defun calcFunc-eq (a b &rest more)
- X (if more
- X (let* ((args (cons a (cons b (copy-sequence more))))
- X (res 1)
- X (p args)
- X p2)
- X (while (and (cdr p) (not (eq res 0)))
- X (setq p2 p)
- X (while (and (setq p2 (cdr p2)) (not (eq res 0)))
- X (setq res (math-two-eq (car p) (car p2)))
- X (if (eq res 1)
- X (setcdr p (delq (car p2) (cdr p)))))
- X (setq p (cdr p)))
- X (if (eq res 0)
- X 0
- X (if (cdr args)
- X (cons 'calcFunc-eq args)
- X 1)))
- X (or (math-two-eq a b)
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-eq (math-neg a) (math-neg b))
- X (list 'calcFunc-eq a b))))
- )
- X
- (defun calcFunc-neq (a b &rest more)
- X (if more
- X (let* ((args (cons a (cons b more)))
- X (res 0)
- X (all t)
- X (p args)
- X p2)
- X (while (and (cdr p) (not (eq res 1)))
- X (setq p2 p)
- X (while (and (setq p2 (cdr p2)) (not (eq res 1)))
- X (setq res (math-two-eq (car p) (car p2)))
- X (or res (setq all nil)))
- X (setq p (cdr p)))
- X (if (eq res 1)
- X 0
- X (if all
- X 1
- X (cons 'calcFunc-neq args))))
- X (or (cdr (assq (math-two-eq a b) '((0 . 1) (1 . 0))))
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-neq (math-neg a) (math-neg b))
- X (list 'calcFunc-neq a b))))
- )
- X
- (defun math-two-eq (a b)
- X (if (eq (car-safe a) 'vec)
- X (if (eq (car-safe b) 'vec)
- X (if (= (length a) (length b))
- X (let ((res 1))
- X (while (and (setq a (cdr a) b (cdr b)) (not (eq res 0)))
- X (if res
- X (setq res (math-two-eq (car a) (car b)))
- X (if (eq (math-two-eq (car a) (car b)) 0)
- X (setq res 0))))
- X res)
- X 0)
- X (if (Math-objectp b)
- X 0
- X nil))
- X (if (eq (car-safe b) 'vec)
- X (if (Math-objectp a)
- X 0
- X nil)
- X (let ((res (math-compare a b)))
- X (if (= res 0)
- X 1
- X (if (and (= res 2) (not (and (Math-scalarp a) (Math-scalarp b))))
- X nil
- X 0)))))
- )
- X
- (defun calcFunc-lt (a b)
- X (let ((res (math-compare a b)))
- X (if (= res -1)
- X 1
- X (if (= res 2)
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-gt (math-neg a) (math-neg b))
- X (list 'calcFunc-lt a b))
- X 0)))
- )
- X
- (defun calcFunc-gt (a b)
- X (let ((res (math-compare a b)))
- X (if (= res 1)
- X 1
- X (if (= res 2)
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-lt (math-neg a) (math-neg b))
- X (list 'calcFunc-gt a b))
- X 0)))
- )
- X
- (defun calcFunc-leq (a b)
- X (let ((res (math-compare a b)))
- X (if (= res 1)
- X 0
- X (if (= res 2)
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-geq (math-neg a) (math-neg b))
- X (list 'calcFunc-leq a b))
- X 1)))
- )
- X
- (defun calcFunc-geq (a b)
- X (let ((res (math-compare a b)))
- X (if (= res -1)
- X 0
- X (if (= res 2)
- X (if (and (or (math-looks-negp a) (math-zerop a))
- X (or (math-looks-negp b) (math-zerop b)))
- X (list 'calcFunc-leq (math-neg a) (math-neg b))
- X (list 'calcFunc-geq a b))
- X 1)))
- )
- X
- (defun calcFunc-rmeq (a)
- X (if (math-vectorp a)
- X (math-map-vec 'calcFunc-rmeq a)
- X (if (assq (car-safe a) calc-tweak-eqn-table)
- X (if (and (eq (car-safe (nth 2 a)) 'var)
- X (math-objectp (nth 1 a)))
- X (nth 1 a)
- X (nth 2 a))
- X (if (eq (car-safe a) 'calcFunc-assign)
- X (nth 2 a)
- X (if (eq (car-safe a) 'calcFunc-evalto)
- X (nth 1 a)
- X (list 'calcFunc-rmeq a)))))
- )
- X
- (defun calcFunc-land (a b)
- X (cond ((Math-zerop a)
- X a)
- X ((Math-zerop b)
- X b)
- X ((math-is-true a)
- X b)
- X ((math-is-true b)
- X a)
- X (t (list 'calcFunc-land a b)))
- )
- X
- (defun calcFunc-lor (a b)
- X (cond ((Math-zerop a)
- X b)
- X ((Math-zerop b)
- X a)
- X ((math-is-true a)
- X a)
- X ((math-is-true b)
- X b)
- X (t (list 'calcFunc-lor a b)))
- )
- X
- (defun calcFunc-lnot (a)
- X (if (Math-zerop a)
- X 1
- X (if (math-is-true a)
- X 0
- X (let ((op (and (= (length a) 3)
- X (assq (car a) calc-tweak-eqn-table))))
- X (if op
- X (cons (nth 2 op) (cdr a))
- X (list 'calcFunc-lnot a)))))
- )
- X
- (defun calcFunc-if (c e1 e2)
- X (if (Math-zerop c)
- X e2
- X (if (and (math-is-true c) (not (Math-vectorp c)))
- X e1
- X (or (and (Math-vectorp c)
- X (math-constp c)
- X (let ((ee1 (if (Math-vectorp e1)
- X (if (= (length c) (length e1))
- X (cdr e1)
- X (calc-record-why "*Dimension error" e1))
- X (list e1)))
- X (ee2 (if (Math-vectorp e2)
- X (if (= (length c) (length e2))
- X (cdr e2)
- X (calc-record-why "*Dimension error" e2))
- X (list e2))))
- X (and ee1 ee2
- X (cons 'vec (math-if-vector (cdr c) ee1 ee2)))))
- X (list 'calcFunc-if c e1 e2))))
- )
- X
- (defun math-if-vector (c e1 e2)
- X (and c
- X (cons (if (Math-zerop (car c)) (car e2) (car e1))
- X (math-if-vector (cdr c)
- X (or (cdr e1) e1)
- X (or (cdr e2) e2))))
- )
- X
- (defun math-normalize-logical-op (a)
- X (or (and (eq (car a) 'calcFunc-if)
- X (= (length a) 4)
- X (let ((a1 (math-normalize (nth 1 a))))
- X (if (Math-zerop a1)
- X (math-normalize (nth 3 a))
- X (if (Math-numberp a1)
- X (math-normalize (nth 2 a))
- X (if (and (Math-vectorp (nth 1 a))
- X (math-constp (nth 1 a)))
- X (calcFunc-if (nth 1 a)
- X (math-normalize (nth 2 a))
- X (math-normalize (nth 3 a)))
- X (let ((calc-simplify-mode 'none))
- X (list 'calcFunc-if a1
- X (math-normalize (nth 2 a))
- X (math-normalize (nth 3 a)))))))))
- X a)
- )
- X
- (defun calcFunc-in (a b)
- X (or (and (eq (car-safe b) 'vec)
- X (let ((bb b))
- X (while (and (setq bb (cdr bb))
- X (not (if (memq (car-safe (car bb)) '(vec intv))
- X (eq (calcFunc-in a (car bb)) 1)
- X (Math-equal a (car bb))))))
- X (if bb 1 (and (math-constp a) (math-constp bb) 0))))
- X (and (eq (car-safe b) 'intv)
- X (let ((res (math-compare a (nth 2 b))) res2)
- X (cond ((= res -1)
- X 0)
- X ((and (= res 0)
- X (or (/= (nth 1 b) 2)
- X (Math-lessp (nth 2 b) (nth 3 b))))
- X (if (memq (nth 1 b) '(2 3)) 1 0))
- X ((= (setq res2 (math-compare a (nth 3 b))) 1)
- X 0)
- X ((and (= res2 0)
- X (or (/= (nth 1 b) 1)
- X (Math-lessp (nth 2 b) (nth 3 b))))
- X (if (memq (nth 1 b) '(1 3)) 1 0))
- X ((/= res 1)
- X nil)
- X ((/= res2 -1)
- X nil)
- X (t 1))))
- X (and (Math-equal a b)
- X 1)
- X (and (math-constp a) (math-constp b)
- X 0)
- X (list 'calcFunc-in a b))
- )
- X
- (defun calcFunc-typeof (a)
- X (cond ((Math-integerp a) 1)
- X ((eq (car a) 'frac) 2)
- X ((eq (car a) 'float) 3)
- X ((eq (car a) 'hms) 4)
- X ((eq (car a) 'cplx) 5)
- X ((eq (car a) 'polar) 6)
- X ((eq (car a) 'sdev) 7)
- X ((eq (car a) 'intv) 8)
- X ((eq (car a) 'mod) 9)
- X ((eq (car a) 'date) (if (Math-integerp (nth 1 a)) 10 11))
- X ((eq (car a) 'var)
- X (if (memq (nth 2 a) '(var-inf var-uinf var-nan)) 12 100))
- X ((eq (car a) 'vec) (if (math-matrixp a) 102 101))
- X (t (math-calcFunc-to-var func)))
- )
- X
- (defun calcFunc-integer (a)
- X (if (Math-integerp a)
- X 1
- X (if (Math-objvecp a)
- X 0
- X (list 'calcFunc-integer a)))
- )
- X
- (defun calcFunc-real (a)
- X (if (Math-realp a)
- X 1
- X (if (Math-objvecp a)
- X 0
- X (list 'calcFunc-real a)))
- )
- X
- (defun calcFunc-constant (a)
- X (if (math-constp a)
- X 1
- X (if (Math-objvecp a)
- X 0
- X (list 'calcFunc-constant a)))
- )
- X
- (defun calcFunc-refers (a b)
- X (if (math-expr-contains a b)
- X 1
- X (if (eq (car-safe a) 'var)
- X (list 'calcFunc-refers a b)
- X 0))
- )
- X
- (defun calcFunc-negative (a)
- X (if (math-looks-negp a)
- X 1
- X (if (or (math-zerop a)
- X (math-posp a))
- X 0
- X (list 'calcFunc-negative a)))
- )
- X
- (defun calcFunc-variable (a)
- X (if (eq (car-safe a) 'var)
- X 1
- X (if (Math-objvecp a)
- X 0
- X (list 'calcFunc-variable a)))
- )
- X
- (defun calcFunc-nonvar (a)
- X (if (eq (car-safe a) 'var)
- X (list 'calcFunc-nonvar a)
- X 1)
- )
- X
- (defun calcFunc-istrue (a)
- X (if (math-is-true a)
- X 1
- X 0)
- )
- X
- X
- X
- X
- ;;;; User-programmability.
- X
- ;;; Compiling Lisp-like forms to use the math library.
- X
- (defun math-do-defmath (func args body)
- X (calc-need-macros)
- X (let* ((fname (intern (concat "calcFunc-" (symbol-name func))))
- X (doc (if (stringp (car body)) (list (car body))))
- X (clargs (mapcar 'math-clean-arg args))
- X (body (math-define-function-body
- X (if (stringp (car body)) (cdr body) body)
- X clargs)))
- X (list 'progn
- X (if (and (consp (car body))
- X (eq (car (car body)) 'interactive))
- X (let ((inter (car body)))
- X (setq body (cdr body))
- X (if (or (> (length inter) 2)
- X (integerp (nth 1 inter)))
- X (let ((hasprefix nil) (hasmulti nil))
- X (if (stringp (nth 1 inter))
- X (progn
- X (cond ((equal (nth 1 inter) "p")
- X (setq hasprefix t))
- X ((equal (nth 1 inter) "m")
- X (setq hasmulti t))
- X (t (error
- X "Can't handle interactive code string \"%s\""
- X (nth 1 inter))))
- X (setq inter (cdr inter))))
- X (if (not (integerp (nth 1 inter)))
- X (error
- X "Expected an integer in interactive specification"))
- X (append (list 'defun
- X (intern (concat "calc-"
- X (symbol-name func)))
- X (if (or hasprefix hasmulti)
- X '(&optional n)
- X ()))
- X doc
- X (if (or hasprefix hasmulti)
- X '((interactive "P"))
- X '((interactive)))
- X (list
- X (append
- X '(calc-slow-wrapper)
- X (and hasmulti
- X (list
- X (list 'setq
- X 'n
- X (list 'if
- X 'n
- X (list 'prefix-numeric-value
- X 'n)
- X (nth 1 inter)))))
- X (list
- X (list 'calc-enter-result
- X (if hasmulti 'n (nth 1 inter))
- X (nth 2 inter)
- X (if hasprefix
- X (list 'append
- X (list 'quote (list fname))
- X (list 'calc-top-list-n
- X (nth 1 inter))
- X (list 'and
- X 'n
- X (list
- X 'list
- X (list
- X 'math-normalize
- X (list
- X 'prefix-numeric-value
- X 'n)))))
- X (list 'cons
- X (list 'quote fname)
- X (list 'calc-top-list-n
- X (if hasmulti
- X 'n
- X (nth 1 inter)))))))))))
- X (append (list 'defun
- X (intern (concat "calc-" (symbol-name func)))
- X args)
- X doc
- X (list
- X inter
- X (cons 'calc-wrapper body))))))
- X (append (list 'defun fname clargs)
- X doc
- X (math-do-arg-list-check args nil nil)
- X body)))
- )
- X
- (defun math-clean-arg (arg)
- X (if (consp arg)
- X (math-clean-arg (nth 1 arg))
- X arg)
- )
- X
- (defun math-do-arg-check (arg var is-opt is-rest)
- X (if is-opt
- X (let ((chk (math-do-arg-check arg var nil nil)))
- X (list (cons 'and
- X (cons var
- X (if (cdr chk)
- X (setq chk (list (cons 'progn chk)))
- X chk)))))
- X (and (consp arg)
- X (let* ((rest (math-do-arg-check (nth 1 arg) var is-opt is-rest))
- X (qual (car arg))
- X (qqual (list 'quote qual))
- X (qual-name (symbol-name qual))
- X (chk (intern (concat "math-check-" qual-name))))
- X (if (fboundp chk)
- X (append rest
- X (list
- X (if is-rest
- X (list 'setq var
- X (list 'mapcar (list 'quote chk) var))
- X (list 'setq var (list chk var)))))
- X (if (fboundp (setq chk (intern (concat "math-" qual-name))))
- X (append rest
- X (list
- X (if is-rest
- X (list 'mapcar
- X (list 'function
- X (list 'lambda '(x)
- X (list 'or
- X (list chk 'x)
- X (list 'math-reject-arg
- X 'x qqual))))
- X var)
- X (list 'or
- X (list chk var)
- X (list 'math-reject-arg var qqual)))))
- X (if (and (string-match "\\`not-\\(.*\\)\\'" qual-name)
- X (fboundp (setq chk (intern
- X (concat "math-"
- X (math-match-substring
- X qual-name 1))))))
- X (append rest
- X (list
- X (if is-rest
- X (list 'mapcar
- X (list 'function
- X (list 'lambda '(x)
- X (list 'and
- X (list chk 'x)
- X (list 'math-reject-arg
- X 'x qqual))))
- X var)
- X (list 'and
- X (list chk var)
- X (list 'math-reject-arg var qqual)))))
- X (error "Unknown qualifier `%s'" qual-name)))))))
- )
- X
- (defun math-do-arg-list-check (args is-opt is-rest)
- X (cond ((null args) nil)
- X ((consp (car args))
- X (append (math-do-arg-check (car args)
- X (math-clean-arg (car args))
- X is-opt is-rest)
- X (math-do-arg-list-check (cdr args) is-opt is-rest)))
- X ((eq (car args) '&optional)
- X (math-do-arg-list-check (cdr args) t nil))
- X ((eq (car args) '&rest)
- X (math-do-arg-list-check (cdr args) nil t))
- X (t (math-do-arg-list-check (cdr args) is-opt is-rest)))
- )
- X
- (defconst math-prim-funcs
- X '( (~= . math-nearly-equal)
- X (% . math-mod)
- X (lsh . calcFunc-lsh)
- X (ash . calcFunc-ash)
- X (logand . calcFunc-and)
- X (logandc2 . calcFunc-diff)
- X (logior . calcFunc-or)
- X (logxor . calcFunc-xor)
- X (lognot . calcFunc-not)
- X (equal . equal) ; need to leave these ones alone!
- X (eq . eq)
- X (and . and)
- X (or . or)
- X (if . if)
- X (^ . math-pow)
- X (expt . math-pow)
- X )
- )
- X
- (defconst math-prim-vars
- X '( (nil . nil)
- X (t . t)
- X (&optional . &optional)
- X (&rest . &rest)
- X )
- )
- X
- (defun math-define-function-body (body env)
- X (let ((body (math-define-body body env)))
- X (if (math-body-refers-to body 'math-return)
- X (list (cons 'catch (cons '(quote math-return) body)))
- X body))
- )
- X
- (defun math-define-body (body exp-env)
- X (math-define-list body)
- )
- X
- (defun math-define-list (body &optional quote)
- X (cond ((null body)
- X nil)
- X ((and (eq (car body) ':)
- X (stringp (nth 1 body)))
- X (cons (let* ((math-read-expr-quotes t)
- X (exp (math-read-plain-expr (nth 1 body) t)))
- X (math-define-exp exp))
- X (math-define-list (cdr (cdr body)))))
- X (quote
- X (cons (cond ((consp (car body))
- X (math-define-list (cdr body) t))
- X (t
- X (car body)))
- X (math-define-list (cdr body))))
- X (t
- X (cons (math-define-exp (car body))
- X (math-define-list (cdr body)))))
- )
- X
- (defun math-define-exp (exp)
- X (cond ((consp exp)
- X (let ((func (car exp)))
- X (cond ((memq func '(quote function))
- X (if (and (consp (nth 1 exp))
- X (eq (car (nth 1 exp)) 'lambda))
- X (cons 'quote
- X (math-define-lambda (nth 1 exp) exp-env))
- X exp))
- X ((memq func '(let let* for foreach))
- X (let ((head (nth 1 exp))
- X (body (cdr (cdr exp))))
- X (if (memq func '(let let*))
- X ()
- X (setq func (cdr (assq func '((for . math-for)
- X (foreach . math-foreach)))))
- X (if (not (listp (car head)))
- X (setq head (list head))))
- X (macroexpand
- X (cons func
- X (cons (math-define-let head)
- X (math-define-body body
- X (nconc
- X (math-define-let-env head)
- X exp-env)))))))
- X ((and (memq func '(setq setf))
- X (math-complicated-lhs (cdr exp)))
- X (if (> (length exp) 3)
- X (cons 'progn (math-define-setf-list (cdr exp)))
- X (math-define-setf (nth 1 exp) (nth 2 exp))))
- X ((eq func 'condition-case)
- X (cons func
- X (cons (nth 1 exp)
- X (math-define-body (cdr (cdr exp))
- X (cons (nth 1 exp)
- X exp-env)))))
- X ((eq func 'cond)
- X (cons func
- X (math-define-cond (cdr exp))))
- X ((and (consp func) ; ('spam a b) == force use of plain spam
- X (eq (car func) 'quote))
- X (cons func (math-define-list (cdr exp))))
- X ((symbolp func)
- X (let ((args (math-define-list (cdr exp)))
- X (prim (assq func math-prim-funcs)))
- X (cond (prim
- X (cons (cdr prim) args))
- X ((eq func 'floatp)
- X (list 'eq (car args) '(quote float)))
- X ((eq func '+)
- X (math-define-binop 'math-add 0
- X (car args) (cdr args)))
- X ((eq func '-)
- X (if (= (length args) 1)
- X (cons 'math-neg args)
- X (math-define-binop 'math-sub 0
- X (car args) (cdr args))))
- X ((eq func '*)
- X (math-define-binop 'math-mul 1
- X (car args) (cdr args)))
- X ((eq func '/)
- X (math-define-binop 'math-div 1
- X (car args) (cdr args)))
- X ((eq func 'min)
- X (math-define-binop 'math-min 0
- X (car args) (cdr args)))
- X ((eq func 'max)
- X (math-define-binop 'math-max 0
- X (car args) (cdr args)))
- X ((eq func '<)
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-negp (car args))
- X (cons 'math-lessp args)))
- X ((eq func '>)
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-posp (car args))
- X (list 'math-lessp (nth 1 args) (nth 0 args))))
- X ((eq func '<=)
- X (list 'not
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-posp (car args))
- X (cons 'math-lessp args))))
- X ((eq func '>=)
- X (list 'not
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-negp (car args))
- X (list 'math-lessp
- X (nth 1 args) (nth 0 args)))))
- X ((eq func '=)
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-zerop (nth 0 args))
- X (if (and (integerp (nth 1 args))
- X (/= (% (nth 1 args) 10) 0))
- X (cons 'math-equal-int args)
- X (cons 'math-equal args))))
- X ((eq func '/=)
- X (list 'not
- X (if (and (math-numberp (nth 1 args))
- X (math-zerop (nth 1 args)))
- X (list 'math-zerop (nth 0 args))
- X (if (and (integerp (nth 1 args))
- X (/= (% (nth 1 args) 10) 0))
- X (cons 'math-equal-int args)
- X (cons 'math-equal args)))))
- X ((eq func '1+)
- X (list 'math-add (car args) 1))
- X ((eq func '1-)
- X (list 'math-add (car args) -1))
- X ((eq func 'not) ; optimize (not (not x)) => x
- X (if (eq (car-safe args) func)
- X (car (nth 1 args))
- X (cons func args)))
- X ((and (eq func 'elt) (cdr (cdr args)))
- X (math-define-elt (car args) (cdr args)))
- X (t
- X (macroexpand
- X (let* ((name (symbol-name func))
- X (cfunc (intern (concat "calcFunc-" name)))
- X (mfunc (intern (concat "math-" name))))
- X (cond ((fboundp cfunc)
- X (cons cfunc args))
- X ((fboundp mfunc)
- X (cons mfunc args))
- X ((or (fboundp func)
- X (string-match "\\`calcFunc-.*" name))
- X (cons func args))
- X (t
- X (cons cfunc args)))))))))
- X (t (cons func args)))))
- X ((symbolp exp)
- X (let ((prim (assq exp math-prim-vars))
- X (name (symbol-name exp)))
- X (cond (prim
- X (cdr prim))
- X ((memq exp exp-env)
- X exp)
- X ((string-match "-" name)
- X exp)
- X (t
- X (intern (concat "var-" name))))))
- X ((integerp exp)
- X (if (or (<= exp -1000000) (>= exp 1000000))
- X (list 'quote (math-normalize exp))
- X exp))
- X (t exp))
- )
- X
- (defun math-define-cond (forms)
- X (and forms
- X (cons (math-define-list (car forms))
- X (math-define-cond (cdr forms))))
- )
- X
- (defun math-complicated-lhs (body)
- X (and body
- X (or (not (symbolp (car body)))
- X (math-complicated-lhs (cdr (cdr body)))))
- )
- X
- (defun math-define-setf-list (body)
- X (and body
- X (cons (math-define-setf (nth 0 body) (nth 1 body))
- X (math-define-setf-list (cdr (cdr body)))))
- )
- X
- (defun math-define-setf (place value)
- X (setq place (math-define-exp place)
- X value (math-define-exp value))
- X (cond ((symbolp place)
- X (list 'setq place value))
- X ((eq (car-safe place) 'nth)
- X (list 'setcar (list 'nthcdr (nth 1 place) (nth 2 place)) value))
- X ((eq (car-safe place) 'elt)
- X (list 'setcar (list 'nthcdr (nth 2 place) (nth 1 place)) value))
- X ((eq (car-safe place) 'car)
- X (list 'setcar (nth 1 place) value))
- X ((eq (car-safe place) 'cdr)
- X (list 'setcdr (nth 1 place) value))
- X (t
- X (error "Bad place form for setf: %s" place)))
- )
- X
- (defun math-define-binop (op ident arg1 rest)
- X (if rest
- X (math-define-binop op ident
- X (list op arg1 (car rest))
- X (cdr rest))
- X (or arg1 ident))
- )
- X
- (defun math-define-let (vlist)
- X (and vlist
- X (cons (if (consp (car vlist))
- X (cons (car (car vlist))
- X (math-define-list (cdr (car vlist))))
- X (car vlist))
- X (math-define-let (cdr vlist))))
- )
- X
- (defun math-define-let-env (vlist)
- X (and vlist
- X (cons (if (consp (car vlist))
- X (car (car vlist))
- X (car vlist))
- X (math-define-let-env (cdr vlist))))
- )
- X
- (defun math-define-lambda (exp exp-env)
- X (nconc (list (nth 0 exp) ; 'lambda
- X (nth 1 exp)) ; arg list
- X (math-define-function-body (cdr (cdr exp))
- X (append (nth 1 exp) exp-env)))
- )
- X
- (defun math-define-elt (seq idx)
- X (if idx
- X (math-define-elt (list 'elt seq (car idx)) (cdr idx))
- X seq)
- )
- X
- X
- X
- ;;; Useful programming macros.
- X
- (defmacro math-while (head &rest body)
- X (let ((body (cons 'while (cons head body))))
- X (if (math-body-refers-to body 'math-break)
- X (cons 'catch (cons '(quote math-break) (list body)))
- X body))
- )
- X
- X
- (defmacro math-for (head &rest body)
- X (let ((body (if head
- X (math-handle-for head body)
- X (cons 'while (cons t body)))))
- X (if (math-body-refers-to body 'math-break)
- X (cons 'catch (cons '(quote math-break) (list body)))
- X body))
- )
- X
- (defun math-handle-for (head body)
- X (let* ((var (nth 0 (car head)))
- X (init (nth 1 (car head)))
- X (limit (nth 2 (car head)))
- X (step (or (nth 3 (car head)) 1))
- X (body (if (cdr head)
- X (list (math-handle-for (cdr head) body))
- X body))
- X (all-ints (and (integerp init) (integerp limit) (integerp step)))
- X (const-limit (or (integerp limit)
- X (and (eq (car-safe limit) 'quote)
- X (math-realp (nth 1 limit)))))
- X (const-step (or (integerp step)
- X (and (eq (car-safe step) 'quote)
- X (math-realp (nth 1 step)))))
- X (save-limit (if const-limit limit (make-symbol "<limit>")))
- X (save-step (if const-step step (make-symbol "<step>"))))
- X (cons 'let
- X (cons (append (if const-limit nil (list (list save-limit limit)))
- X (if const-step nil (list (list save-step step)))
- X (list (list var init)))
- X (list
- X (cons 'while
- X (cons (if all-ints
- X (if (> step 0)
- X (list '<= var save-limit)
- X (list '>= var save-limit))
- X (list 'not
- X (if const-step
- X (if (or (math-posp step)
- X (math-posp
- X (cdr-safe step)))
- X (list 'math-lessp
- X save-limit
- X var)
- X (list 'math-lessp
- X var
- X save-limit))
- X (list 'if
- X (list 'math-posp
- X save-step)
- X (list 'math-lessp
- X save-limit
- X var)
- X (list 'math-lessp
- X var
- X save-limit)))))
- X (append body
- X (list (list 'setq
- X var
- X (list (if all-ints
- X '+
- X 'math-add)
- X var
- X save-step))))))))))
- )
- X
- X
- (defmacro math-foreach (head &rest body)
- X (let ((body (math-handle-foreach head body)))
- X (if (math-body-refers-to body 'math-break)
- X (cons 'catch (cons '(quote math-break) (list body)))
- X body))
- )
- X
- X
- (defun math-handle-foreach (head body)
- X (let ((var (nth 0 (car head)))
- X (data (nth 1 (car head)))
- X (body (if (cdr head)
- X (list (math-handle-foreach (cdr head) body))
- X body)))
- X (cons 'let
- X (cons (list (list var data))
- X (list
- X (cons 'while
- X (cons var
- X (append body
- X (list (list 'setq
- X var
- X (list 'cdr var))))))))))
- )
- X
- X
- (defun math-body-refers-to (body thing)
- X (or (equal body thing)
- X (and (consp body)
- X (or (math-body-refers-to (car body) thing)
- X (math-body-refers-to (cdr body) thing))))
- )
- X
- (defun math-break (&optional value)
- X (throw 'math-break value)
- )
- X
- (defun math-return (&optional value)
- X (throw 'math-return value)
- )
- X
- X
- X
- X
- X
- (defun math-composite-inequalities (x op)
- X (if (memq (nth 1 op) '(calcFunc-eq calcFunc-neq))
- X (if (eq (car x) (nth 1 op))
- X (append x (list (math-read-expr-level (nth 3 op))))
- X (throw 'syntax "Syntax error"))
- X (list 'calcFunc-in
- X (nth 2 x)
- X (if (memq (nth 1 op) '(calcFunc-lt calcFunc-leq))
- X (if (memq (car x) '(calcFunc-lt calcFunc-leq))
- X (math-make-intv
- X (+ (if (eq (car x) 'calcFunc-leq) 2 0)
- X (if (eq (nth 1 op) 'calcFunc-leq) 1 0))
- X (nth 1 x) (math-read-expr-level (nth 3 op)))
- X (throw 'syntax "Syntax error"))
- X (if (memq (car x) '(calcFunc-gt calcFunc-geq))
- X (math-make-intv
- X (+ (if (eq (nth 1 op) 'calcFunc-geq) 2 0)
- X (if (eq (car x) 'calcFunc-geq) 1 0))
- X (math-read-expr-level (nth 3 op)) (nth 1 x))
- X (throw 'syntax "Syntax error")))))
- )
- X
- SHAR_EOF
- echo 'File calc-prog.el is complete' &&
- chmod 0644 calc-prog.el ||
- echo 'restore of calc-prog.el failed'
- Wc_c="`wc -c < 'calc-prog.el'`"
- test 60998 -eq "$Wc_c" ||
- echo 'calc-prog.el: original size 60998, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= calc-rewr.el ==============
- if test -f 'calc-rewr.el' -a X"$1" != X"-c"; then
- echo 'x - skipping calc-rewr.el (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting calc-rewr.el (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'calc-rewr.el' &&
- ;; Calculator for GNU Emacs, part II [calc-rewr.el]
- ;; Copyright (C) 1990, 1991 Free Software Foundation, Inc.
- ;; Written by Dave Gillespie, daveg@csvax.cs.caltech.edu.
- X
- ;; This file is part of GNU Emacs.
- X
- ;; GNU Emacs is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY. No author or distributor
- ;; accepts responsibility to anyone for the consequences of using it
- ;; or for whether it serves any particular purpose or works at all,
- ;; unless he says so in writing. Refer to the GNU Emacs General Public
- ;; License for full details.
- X
- ;; Everyone is granted permission to copy, modify and redistribute
- ;; GNU Emacs, but only under the conditions described in the
- ;; GNU Emacs General Public License. A copy of this license is
- ;; supposed to have been given to you along with GNU Emacs so you
- ;; can know your rights and responsibilities. It should be in a
- ;; file named COPYING. Among other things, the copyright notice
- ;; and this notice must be preserved on all copies.
- X
- X
- X
- ;; This file is autoloaded from calc-ext.el.
- (require 'calc-ext)
- X
- (require 'calc-macs)
- X
- (defun calc-Need-calc-rewr () nil)
- X
- X
- (defun calc-rewrite-selection (rules-str &optional many prefix)
- X (interactive "sRewrite rule(s): \np")
- X (calc-slow-wrapper
- X (calc-preserve-point)
- X (let* ((num (max 1 (calc-locate-cursor-element (point))))
- X (reselect t)
- X (pop-rules nil)
- X (entry (calc-top num 'entry))
- X (expr (car entry))
- X (sel (calc-auto-selection entry))
- X (math-rewrite-selections t)
- X (math-rewrite-default-iters 1))
- X (if (or (null rules-str) (equal rules-str "") (equal rules-str "$"))
- X (if (= num 1)
- X (error "Can't use same stack entry for formula and rules.")
- X (setq rules (calc-top-n 1 t)
- X pop-rules t))
- X (setq rules (if (stringp rules-str)
- X (math-read-exprs rules-str) rules-str))
- X (if (eq (car-safe rules) 'error)
- X (error "Bad format in expression: %s" (nth 1 rules)))
- X (if (= (length rules) 1)
- X (setq rules (car rules))
- X (setq rules (cons 'vec rules)))
- X (or (memq (car-safe rules) '(vec var calcFunc-assign
- X calcFunc-condition))
- X (let ((rhs (math-read-expr
- X (read-string (concat "Rewrite from: " rules-str
- X " to: ")))))
- X (if (eq (car-safe rhs) 'error)
- X (error "Bad format in expression: %s" (nth 1 rhs)))
- X (setq rules (list 'calcFunc-assign rules rhs))))
- X (or (eq (car-safe rules) 'var)
- X (calc-record rules "rule")))
- X (if (eq many 0)
- X (setq many '(var inf var-inf))
- X (if many (setq many (prefix-numeric-value many))))
- X (if sel
- X (setq expr (calc-replace-sub-formula (car entry)
- X sel
- X (list 'calcFunc-select sel)))
- X (setq expr (car entry)
- X reselect nil
- X math-rewrite-selections nil))
- X (setq expr (calc-encase-atoms
- X (calc-normalize
- X (math-rewrite
- X (calc-normalize expr)
- X rules many)))
- X sel nil
- X expr (calc-locate-select-marker expr))
- X (or (consp sel) (setq sel nil))
- X (if pop-rules (calc-pop-stack 1))
- X (calc-pop-push-record-list 1 (or prefix "rwrt") (list expr)
- X (- num (if pop-rules 1 0))
- X (list (and reselect sel))))
- X (calc-handle-whys))
- )
- X
- (defun calc-locate-select-marker (expr) ; changes "sel"
- X (if (Math-primp expr)
- X expr
- X (if (and (eq (car expr) 'calcFunc-select)
- X (= (length expr) 2))
- X (progn
- X (setq sel (if sel t (nth 1 expr)))
- X (nth 1 expr))
- X (cons (car expr)
- X (mapcar 'calc-locate-select-marker (cdr expr)))))
- )
- X
- X
- X
- (defun calc-rewrite (rules-str many)
- X (interactive "sRewrite rule(s): \nP")
- X (calc-slow-wrapper
- X (let (n rules expr)
- X (if (or (null rules-str) (equal rules-str "") (equal rules-str "$"))
- X (setq expr (calc-top-n 2)
- X rules (calc-top-n 1 t)
- X n 2)
- X (setq rules (if (stringp rules-str)
- X (math-read-exprs rules-str) rules-str))
- X (if (eq (car-safe rules) 'error)
- X (error "Bad format in expression: %s" (nth 1 rules)))
- X (if (= (length rules) 1)
- X (setq rules (car rules))
- X (setq rules (cons 'vec rules)))
- X (or (memq (car-safe rules) '(vec var calcFunc-assign
- X calcFunc-condition))
- X (let ((rhs (math-read-expr
- X (read-string (concat "Rewrite from: " rules-str
- X " to: ")))))
- X (if (eq (car-safe rhs) 'error)
- X (error "Bad format in expression: %s" (nth 1 rhs)))
- X (setq rules (list 'calcFunc-assign rules rhs))))
- X (or (eq (car-safe rules) 'var)
- X (calc-record rules "rule"))
- X (setq expr (calc-top-n 1)
- X n 1))
- X (if (eq many 0)
- X (setq many '(var inf var-inf))
- X (if many (setq many (prefix-numeric-value many))))
- X (setq expr (calc-normalize (math-rewrite expr rules many)))
- X (let (sel)
- X (setq expr (calc-locate-select-marker expr)))
- X (calc-pop-push-record-list n "rwrt" (list expr)))
- X (calc-handle-whys))
- )
- X
- (defun calc-match (pat)
- X (interactive "sPattern: \n")
- X (calc-slow-wrapper
- X (let (n expr)
- X (if (or (null pat) (equal pat "") (equal pat "$"))
- X (setq expr (calc-top-n 2)
- X pat (calc-top-n 1)
- X n 2)
- X (if (interactive-p) (setq calc-previous-alg-entry pat))
- X (setq pat (if (stringp pat) (math-read-expr pat) pat))
- X (if (eq (car-safe pat) 'error)
- X (error "Bad format in expression: %s" (nth 1 pat)))
- X (if (not (eq (car-safe pat) 'var))
- X (calc-record pat "pat"))
- X (setq expr (calc-top-n 1)
- X n 1))
- X (or (math-vectorp expr) (error "Argument must be a vector"))
- X (if (calc-is-inverse)
- X (calc-enter-result n "mtcn" (math-match-patterns pat expr t))
- X (calc-enter-result n "mtch" (math-match-patterns pat expr nil)))))
- )
- X
- X
- X
- (defun math-rewrite (whole-expr rules &optional mmt-many)
- X (let ((crules (math-compile-rewrites rules))
- X (heads (math-rewrite-heads whole-expr))
- X (trace-buffer (get-buffer "*Trace*"))
- X (calc-display-just 'center)
- X (calc-display-origin 39)
- X (calc-line-breaking 78)
- X (calc-line-numbering nil)
- X (calc-show-selections t)
- X (calc-why nil)
- X (mmt-func (function
- X (lambda (x)
- X (let ((result (math-apply-rewrites x (cdr crules)
- X heads crules)))
- X (if result
- X (progn
- X (if trace-buffer
- X (let ((fmt (math-format-stack-value
- X (list result nil nil))))
- X (save-excursion
- X (set-buffer trace-buffer)
- X (insert "\nrewrite to\n" fmt "\n"))))
- X (setq heads (math-rewrite-heads result heads t))))
- X result)))))
- X (if trace-buffer
- X (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
- X (save-excursion
- X (set-buffer trace-buffer)
- X (setq truncate-lines t)
- X (goto-char (point-max))
- X (insert "\n\nBegin rewriting\n" fmt "\n"))))
- X (or mmt-many (setq mmt-many (or (nth 1 (car crules))
- X math-rewrite-default-iters)))
- X (if (equal mmt-many '(var inf var-inf)) (setq mmt-many 1000000))
- X (if (equal mmt-many '(neg (var inf var-inf))) (setq mmt-many -1000000))
- X (math-rewrite-phase (nth 3 (car crules)))
- X (if trace-buffer
- X (let ((fmt (math-format-stack-value (list whole-expr nil nil))))
- X (save-excursion
- X (set-buffer trace-buffer)
- X (insert "\nDone rewriting"
- X (if (= mmt-many 0) " (reached iteration limit)" "")
- X ":\n" fmt "\n"))))
- X whole-expr)
- )
- (setq math-rewrite-default-iters 100)
- X
- (defun math-rewrite-phase (sched)
- X (while (and sched (/= mmt-many 0))
- X (if (listp (car sched))
- X (while (let ((save-expr whole-expr))
- X (math-rewrite-phase (car sched))
- X (not (equal whole-expr save-expr))))
- X (if (symbolp (car sched))
- X (progn
- X (setq whole-expr (math-normalize (list (car sched) whole-expr)))
- X (if trace-buffer
- X (let ((fmt (math-format-stack-value
- X (list whole-expr nil nil))))
- X (save-excursion
- X (set-buffer trace-buffer)
- X (insert "\ncall "
- X (substring (symbol-name (car sched)) 9)
- X ":\n" fmt "\n")))))
- X (let ((math-rewrite-phase (car sched)))
- X (if trace-buffer
- X (save-excursion
- X (set-buffer trace-buffer)
- X (insert (format "\n(Phase %d)\n" math-rewrite-phase))))
- X (while (let ((save-expr whole-expr))
- X (setq whole-expr (math-normalize
- X (math-map-tree-rec whole-expr)))
- X (not (equal whole-expr save-expr)))))))
- X (setq sched (cdr sched)))
- )
- X
- (defun calcFunc-rewrite (expr rules &optional many)
- X (or (null many) (integerp many)
- X (equal many '(var inf var-inf)) (equal many '(neg (var inf var-inf)))
- X (math-reject-arg many 'fixnump))
- X (condition-case err
- X (math-rewrite expr rules (or many 1))
- X (error (math-reject-arg rules (nth 1 err))))
- )
- X
- (defun calcFunc-match (pat vec)
- X (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
- X (condition-case err
- X (math-match-patterns pat vec nil)
- X (error (math-reject-arg pat (nth 1 err))))
- )
- X
- (defun calcFunc-matchnot (pat vec)
- X (or (math-vectorp vec) (math-reject-arg vec 'vectorp))
- X (condition-case err
- X (math-match-patterns pat vec t)
- X (error (math-reject-arg pat (nth 1 err))))
- )
- X
- (defun math-match-patterns (pat vec &optional not-flag)
- X (let ((newvec nil)
- X (crules (math-compile-patterns pat)))
- X (while (setq vec (cdr vec))
- X (if (eq (not (math-apply-rewrites (car vec) crules))
- X not-flag)
- X (setq newvec (cons (car vec) newvec))))
- X (cons 'vec (nreverse newvec)))
- )
- X
- (defun calcFunc-matches (expr pat)
- X (condition-case err
- X (if (math-apply-rewrites expr (math-compile-patterns pat))
- X 1
- X 0)
- X (error (math-reject-arg pat (nth 1 err))))
- )
- X
- X
- X
- ;;; A compiled rule set is an a-list of entries whose cars are functors,
- ;;; and whose cdrs are lists of rules. If there are rules with no
- ;;; well-defined head functor, they are included on all lists and also
- ;;; on an extra list whose car is nil.
- ;;;
- ;;; The first entry in the a-list is of the form (schedule A B C ...).
- ;;;
- ;;; Rule list entries take the form (regs prog head phases), where:
- ;;;
- ;;; regs is a vector of match registers.
- ;;;
- ;;; prog is a match program (see below).
- ;;;
- ;;; head is a rare function name appearing in the rule body (but not the
- ;;; head of the whole rule), or nil if none.
- ;;;
- ;;; phases is a list of phase numbers for which the rule is enabled.
- ;;;
- ;;; A match program is a list of match instructions.
- ;;;
- ;;; In the following, "part" is a register number that contains the
- ;;; subexpression to be operated on.
- ;;;
- ;;; Register 0 is the whole expression being matched. The others are
- ;;; meta-variables in the pattern, temporaries used for matching and
- ;;; backtracking, and constant expressions.
- ;;;
- ;;; (same part reg)
- ;;; The selected part must be math-equal to the contents of "reg".
- ;;;
- ;;; (same-neg part reg)
- ;;; The selected part must be math-equal to the negative of "reg".
- ;;;
- ;;; (copy part reg)
- ;;; The selected part is copied into "reg". (Rarely used.)
- ;;;
- ;;; (copy-neg part reg)
- ;;; The negative of the selected part is copied into "reg".
- ;;;
- ;;; (integer part)
- ;;; The selected part must be an integer.
- ;;;
- ;;; (real part)
- ;;; The selected part must be a real.
- ;;;
- ;;; (constant part)
- ;;; The selected part must be a constant.
- ;;;
- ;;; (negative part)
- ;;; The selected part must "look" negative.
- ;;;
- ;;; (rel part op reg)
- ;;; The selected part must satisfy "part op reg", where "op"
- ;;; is one of the 6 relational ops, and "reg" is a register.
- ;;;
- ;;; (mod part modulo value)
- ;;; The selected part must satisfy "part % modulo = value", where
- ;;; "modulo" and "value" are constants.
- ;;;
- ;;; (func part head reg1 reg2 ... regn)
- ;;; The selected part must be an n-ary call to function "head".
- ;;; The arguments are stored in "reg1" through "regn".
- ;;;
- ;;; (func-def part head defs reg1 reg2 ... regn)
- ;;; The selected part must be an n-ary call to function "head".
- ;;; "Defs" is a list of value/register number pairs for default args.
- ;;; If a match, assign default values to registers and then skip
- ;;; immediately over any following "func-def" instructions and
- ;;; the following "func" instruction. If wrong number of arguments,
- ;;; proceed to the following "func-def" or "func" instruction.
- ;;;
- ;;; (func-opt part head defs reg1)
- ;;; Like func-def with "n=1", except that if the selected part is
- ;;; not a call to "head", then the part itself successfully matches
- ;;; "reg1" (and the defaults are assigned).
- ;;;
- ;;; (try part heads mark reg1 [def])
- ;;; The selected part must be a function of the correct type which is
- ;;; associative and/or commutative. "Heads" is a list of acceptable
- ;;; types. An initial assignment of arguments to "reg1" is tried.
- ;;; If the program later fails, it backtracks to this instruction
- ;;; and tries other assignments of arguments to "reg1".
- ;;; If "def" exists and normal matching fails, backtrack and assign
- ;;; "part" to "reg1", and "def" to "reg2" in the following "try2".
- ;;; The "mark" is a vector of size 5; only "mark[3-4]" are initialized.
- ;;; "mark[0]" points to the argument list; "mark[1]" points to the
- ;;; current argument; "mark[2]" is 0 if there are two arguments,
- ;;; 1 if reg1 is matching single arguments, 2 if reg2 is matching
- ;;; single arguments (a+b+c+d is never split as (a+b)+(c+d)), or
- ;;; 3 if reg2 is matching "def"; "mark[3]" is 0 if the function must
- ;;; have two arguments, 1 if phase-2 can be skipped, 2 if full
- ;;; backtracking is necessary; "mark[4]" is t if the arguments have
- ;;; been switched from the order given in the original pattern.
- ;;;
- ;;; (try2 try reg2)
- ;;; Every "try" will be followed by a "try2" whose "try" field is
- ;;; a pointer to the corresponding "try". The arguments which were
- ;;; not stored in "reg1" by that "try" are now stored in "reg2".
- ;;;
- ;;; (alt instr nil mark)
- ;;; Basic backtracking. Execute the instruction sequence "instr".
- ;;; If this fails, back up and execute following the "alt" instruction.
- ;;; The "mark" must be the vector "[nil nil 4]". The "instr" sequence
- ;;; should execute "end-alt" at the end.
- ;;;
- ;;; (end-alt ptr)
- ;;; Register success of the first alternative of a previous "alt".
- ;;; "Ptr" is a pointer to the next instruction following that "alt".
- ;;;
- ;;; (apply part reg1 reg2)
- ;;; The selected part must be a function call. The functor
- ;;; (as a variable name) is stored in "reg1"; the arguments
- ;;; (as a vector) are stored in "reg2".
- ;;;
- ;;; (cons part reg1 reg2)
- ;;; The selected part must be a nonempty vector. The first element
- ;;; of the vector is stored in "reg1"; the rest of the vector
- ;;; (as another vector) is stored in "reg2".
- ;;;
- ;;; (rcons part reg1 reg2)
- ;;; The selected part must be a nonempty vector. The last element
- ;;; of the vector is stored in "reg2"; the rest of the vector
- ;;; (as another vector) is stored in "reg1".
- ;;;
- ;;; (select part reg)
- ;;; If the selected part is a unary call to function "select", its
- SHAR_EOF
- true || echo 'restore of calc-rewr.el failed'
- fi
- echo 'End of part 24'
- echo 'File calc-rewr.el is continued in part 25'
- echo 25 > _shar_seq_.tmp
- exit 0
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-