;;; calc-prog.el --- user programmability functions for Calc
-;; Copyright (C) 1990, 1991, 1992, 1993, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 1990-1993, 2001-2013 Free Software Foundation, Inc.
;; Author: David Gillespie <daveg@synaptics.com>
;; Maintainer: Jay Belanger <jay.p.belanger@gmail.com>
(interactive)
(calc-wrapper
(let* ((form (calc-top 1))
- (arglist nil)
+ (math-arglist nil)
(is-lambda (and (eq (car-safe form) 'calcFunc-lambda)
(>= (length form) 2)))
odef key keyname cmd cmd-base cmd-base-default
func calc-user-formula-alist is-symb)
(if is-lambda
- (setq arglist (mapcar (function (lambda (x) (nth 1 x)))
+ (setq math-arglist (mapcar (function (lambda (x) (nth 1 x)))
(nreverse (cdr (reverse (cdr form)))))
form (nth (1- (length form)) form))
(calc-default-formula-arglist form)
- (setq arglist (sort arglist 'string-lessp)))
+ (setq math-arglist (sort math-arglist 'string-lessp)))
(message "Define user key: z-")
(setq key (read-char))
(if (= (calc-user-function-classify key) 0)
(while
(progn
(setq cmd-base-default (concat "User-" keyname))
- (setq cmd (completing-read
+ (setq cmd (completing-read
(concat "Define M-x command name (default calc-"
cmd-base-default
"): ")
"That name conflicts with a built-in Emacs function. Replace this function? "))))))
(while
(progn
- (setq cmd-base-default
+ (setq cmd-base-default
(if cmd-base
(if (string-match
"\\`User-.+" cmd-base)
(substring cmd-base 5))
cmd-base)
(concat "User" keyname)))
- (setq func
+ (setq func
(concat "calcFunc-"
- (completing-read
+ (completing-read
(concat "Define algebraic function name (default "
cmd-base-default "): ")
(mapcar (lambda (x) (substring x 9))
(all-completions "calcFunc-"
obarray))
- (lambda (x)
- (fboundp
+ (lambda (x)
+ (fboundp
(intern (concat "calcFunc-" x))))
nil)))
(setq func
(format "%05d" (% (random) 10000)))))))
(if is-lambda
- (setq calc-user-formula-alist arglist)
+ (setq calc-user-formula-alist math-arglist)
(while
(progn
- (setq calc-user-formula-alist
+ (setq calc-user-formula-alist
(read-from-minibuffer "Function argument list: "
- (if arglist
- (prin1-to-string arglist)
+ (if math-arglist
+ (prin1-to-string math-arglist)
"()")
minibuffer-local-map
t))
- (and (not (calc-subsetp calc-user-formula-alist arglist))
+ (and (not (calc-subsetp calc-user-formula-alist math-arglist))
(not (y-or-n-p
"Okay for arguments that don't appear in formula to be ignored? "))))))
(setq is-symb (and calc-user-formula-alist
func
(y-or-n-p
"Leave it symbolic for non-constant arguments? ")))
- (setq calc-user-formula-alist
+ (setq calc-user-formula-alist
(mapcar (function (lambda (x)
(or (cdr (assq x '((nil . arg-nil)
(t . arg-t))))
(setcdr kmap (cons (cons key cmd) (cdr kmap)))))))
(message "")))
+(defvar math-arglist) ; dynamically bound in all callers
(defun calc-default-formula-arglist (form)
(if (consp form)
(if (eq (car form) 'var)
- (if (or (memq (nth 1 form) arglist)
+ (if (or (memq (nth 1 form) math-arglist)
(math-const-var form))
()
- (setq arglist (cons (nth 1 form) arglist)))
+ (setq math-arglist (cons (nth 1 form) math-arglist)))
(calc-default-formula-arglist-step (cdr form)))))
(defun calc-default-formula-arglist-step (l)
(if (eq calc-language 'unform)
(error "Can't define formats for unformatted mode"))
(let* ((comp (calc-top 1))
- (func (intern
+ (func (intern
(concat "calcFunc-"
(completing-read "Define format for which function: "
(mapcar (lambda (x) (substring x 9))
(all-completions "calcFunc-"
obarray))
- (lambda (x)
- (fboundp
+ (lambda (x)
+ (fboundp
(intern (concat "calcFunc-" x))))))))
(comps (get func 'math-compose-forms))
entry entry2
- (arglist nil)
+ (math-arglist nil)
(calc-user-formula-alist nil))
(if (math-zerop comp)
(if (setq entry (assq calc-language comps))
(put func 'math-compose-forms (delq entry comps)))
(calc-default-formula-arglist comp)
- (setq arglist (sort arglist 'string-lessp))
+ (setq math-arglist (sort math-arglist 'string-lessp))
(while
(progn
- (setq calc-user-formula-alist
+ (setq calc-user-formula-alist
(read-from-minibuffer "Composition argument list: "
- (if arglist
- (prin1-to-string arglist)
+ (if math-arglist
+ (prin1-to-string math-arglist)
"()")
minibuffer-local-map
t))
- (and (not (calc-subsetp calc-user-formula-alist arglist))
+ (and (not (calc-subsetp calc-user-formula-alist math-arglist))
(y-or-n-p
"Okay for arguments that don't appear in formula to be invisible? "))))
(or (setq entry (assq calc-language comps))
(cons (setq entry (list calc-language)) comps)))
(or (setq entry2 (assq (length calc-user-formula-alist) (cdr entry)))
(setcdr entry
- (cons (setq entry2
+ (cons (setq entry2
(list (length calc-user-formula-alist))) (cdr entry))))
- (setcdr entry2
+ (setcdr entry2
(list 'lambda calc-user-formula-alist (calc-fix-user-formula comp))))
(calc-pop-stack 1)
(calc-do-refresh))))
(switch-to-buffer calc-original-buffer))
;; The variable calc-lang is local to calc-write-parse-table, but is
-;; used by calc-write-parse-table-part which is called by
-;; calc-write-parse-table. The variable is also local to
+;; used by calc-write-parse-table-part which is called by
+;; calc-write-parse-table. The variable is also local to
;; calc-read-parse-table, but is used by calc-fix-token-name which
;; is called (indirectly) by calc-read-parse-table.
(defvar calc-lang)
(let ((pos (point)))
(end-of-line)
(let* ((str (buffer-substring pos (point)))
- (exp (save-excursion
- (set-buffer calc-buf)
+ (exp (with-current-buffer calc-buf
(let ((calc-user-parse-tables nil)
(calc-language nil)
(math-expr-opers (math-standard-ops))
(error "Separator not allowed with { ... }?"))
(if (string-match "\\`\"" sep)
(setq sep (read-from-string sep)))
- (setq sep (calc-fix-token-name sep))
+ (if (> (length sep) 0)
+ (setq sep (calc-fix-token-name sep)))
(setq part (nconc part
(list (list sym p
(and (> (length sep) 0)
(let* ((mac (elt (nth 1 (nth 3 cmd)) 1))
(str (edmacro-format-keys mac t))
(kys (nth 3 (nth 3 cmd))))
- (calc-edit-mode
+ (calc-edit-mode
(list 'calc-edit-macro-finish-edit cmdname kys)
- t (format (concat
- "Editing keyboard macro (%s, bound to %s).\n"
+ t (format (concat
+ "Editing keyboard macro (%s, bound to %s).\n"
"Original keys: %s \n")
cmdname kys (elt (nth 1 (nth 3 cmd)) 0)))
(insert str "\n")
(if (and defn (calc-valid-formula-func func))
(let ((niceexpr (math-format-nice-expr defn (frame-width))))
(calc-wrapper
- (calc-edit-mode
+ (calc-edit-mode
(list 'calc-finish-formula-edit (list 'quote func))
nil
(format (concat
(when match
(kill-line 1)
(setq line (concat line (substring curline 0 match))))
- (setq line (replace-regexp-in-string "SPC" " SPC "
+ (setq line (replace-regexp-in-string "SPC" " SPC "
(replace-regexp-in-string " " "" line)))
(insert line "\t\t\t")
(if (> (current-column) 24)
(setq line (concat line curline))
(kill-line 1)
(setq curline (calc-edit-macro-command)))
- (when match
+ (when match
(kill-line 1)
(setq line (concat line (substring curline 0 match))))
(setq line (replace-regexp-in-string " " "" line))
(setq line (concat line curline))
(kill-line 1)
(setq curline (calc-edit-macro-command)))
- (when match
+ (when match
(kill-line 1)
(setq line (concat line (substring curline 0 match))))
(setq line (replace-regexp-in-string " " "" line))
(mapcar (lambda (x) (substring x 9))
(all-completions "calcFunc-"
obarray))
- (lambda (x)
- (fboundp
+ (lambda (x)
+ (fboundp
(intern (concat "calcFunc-" x))))
t)))))
(and (eq key ?\M-x)
(calc-pop-stack 1)
(if (math-is-true cond)
(if defining-kbd-macro
- (message "If true.."))
+ (message "If true..."))
(if defining-kbd-macro
(message "Condition is false; skipping to Z: or Z] ..."))
(calc-kbd-skip-to-else-if t)))))
(let* ((count 0)
(parts nil)
(body "")
- (open last-command-char)
+ (open last-command-event)
(counter initial)
ch)
(or executing-kbd-macro
(defun math-do-defmath (func args body)
(require 'calc-macs)
(let* ((fname (intern (concat "calcFunc-" (symbol-name func))))
- (doc (if (stringp (car body)) (list (car body))))
+ (doc (if (stringp (car body))
+ (prog1 (list (car body))
+ (setq body (cdr body)))))
(clargs (mapcar 'math-clean-arg args))
- (body (math-define-function-body
- (if (stringp (car body)) (cdr body) body)
- clargs)))
- (list 'progn
- (if (and (consp (car body))
- (eq (car (car body)) 'interactive))
- (let ((inter (car body)))
- (setq body (cdr body))
- (if (or (> (length inter) 2)
- (integerp (nth 1 inter)))
- (let ((hasprefix nil) (hasmulti nil))
- (if (stringp (nth 1 inter))
- (progn
- (cond ((equal (nth 1 inter) "p")
- (setq hasprefix t))
- ((equal (nth 1 inter) "m")
- (setq hasmulti t))
- (t (error
- "Can't handle interactive code string \"%s\""
- (nth 1 inter))))
- (setq inter (cdr inter))))
- (if (not (integerp (nth 1 inter)))
- (error
- "Expected an integer in interactive specification"))
- (append (list 'defun
- (intern (concat "calc-"
- (symbol-name func)))
- (if (or hasprefix hasmulti)
- '(&optional n)
- ()))
- doc
- (if (or hasprefix hasmulti)
- '((interactive "P"))
- '((interactive)))
- (list
- (append
- '(calc-slow-wrapper)
- (and hasmulti
- (list
- (list 'setq
- 'n
- (list 'if
- 'n
- (list 'prefix-numeric-value
- 'n)
- (nth 1 inter)))))
- (list
- (list 'calc-enter-result
- (if hasmulti 'n (nth 1 inter))
- (nth 2 inter)
- (if hasprefix
- (list 'append
- (list 'quote (list fname))
- (list 'calc-top-list-n
- (nth 1 inter))
- (list 'and
- 'n
- (list
- 'list
- (list
- 'math-normalize
- (list
- 'prefix-numeric-value
- 'n)))))
- (list 'cons
- (list 'quote fname)
- (list 'calc-top-list-n
- (if hasmulti
- 'n
- (nth 1 inter)))))))))))
- (append (list 'defun
- (intern (concat "calc-" (symbol-name func)))
- args)
- doc
- (list
- inter
- (cons 'calc-wrapper body))))))
- (append (list 'defun fname clargs)
- doc
- (math-do-arg-list-check args nil nil)
- body))))
+ (inter (if (and (consp (car body))
+ (eq (car (car body)) 'interactive))
+ (prog1 (car body)
+ (setq body (cdr body))))))
+ (setq body (math-define-function-body body clargs))
+ `(progn
+ ,(if inter
+ (if (or (> (length inter) 2)
+ (integerp (nth 1 inter)))
+ (let ((hasprefix nil) (hasmulti nil))
+ (when (stringp (nth 1 inter))
+ (cond ((equal (nth 1 inter) "p")
+ (setq hasprefix t))
+ ((equal (nth 1 inter) "m")
+ (setq hasmulti t))
+ (t (error
+ "Can't handle interactive code string \"%s\""
+ (nth 1 inter))))
+ (setq inter (cdr inter)))
+ (unless (integerp (nth 1 inter))
+ (error "Expected an integer in interactive specification"))
+ `(defun ,(intern (concat "calc-" (symbol-name func)))
+ ,(if (or hasprefix hasmulti) '(&optional n) ())
+ ,@doc
+ (interactive ,@(if (or hasprefix hasmulti) '("P")))
+ (calc-slow-wrapper
+ ,@(if hasmulti
+ `((setq n (if n
+ (prefix-numeric-value n)
+ ,(nth 1 inter)))))
+ (calc-enter-result
+ ,(if hasmulti 'n (nth 1 inter))
+ ,(nth 2 inter)
+ ,(if hasprefix
+ `(append '(,fname)
+ (calc-top-list-n ,(nth 1 inter))
+ (and n
+ (list
+ (math-normalize
+ (prefix-numeric-value n)))))
+ `(cons ',fname
+ (calc-top-list-n
+ ,(if hasmulti
+ 'n
+ (nth 1 inter)))))))))
+ `(defun ,(intern (concat "calc-" (symbol-name func))) ,clargs
+ ,@doc
+ ,inter
+ (calc-wrapper ,@body))))
+ (defun ,fname ,clargs
+ ,@doc
+ ,@(math-do-arg-list-check args nil nil)
+ ,@body))))
(defun math-clean-arg (arg)
(if (consp arg)
(list (cons 'and
(cons var
(if (cdr chk)
- (setq chk (list (cons 'progn chk)))
+ `((progn ,@chk))
chk)))))
- (and (consp arg)
- (let* ((rest (math-do-arg-check (nth 1 arg) var is-opt is-rest))
- (qual (car arg))
- (qqual (list 'quote qual))
- (qual-name (symbol-name qual))
- (chk (intern (concat "math-check-" qual-name))))
- (if (fboundp chk)
- (append rest
- (list
+ (when (consp arg)
+ (let* ((rest (math-do-arg-check (nth 1 arg) var is-opt is-rest))
+ (qual (car arg))
+ (qual-name (symbol-name qual))
+ (chk (intern (concat "math-check-" qual-name))))
+ (if (fboundp chk)
+ (append rest
+ (if is-rest
+ `((setq ,var (mapcar ',chk ,var)))
+ `((setq ,var (,chk ,var)))))
+ (if (fboundp (setq chk (intern (concat "math-" qual-name))))
+ (append rest
+ (if is-rest
+ `((mapcar #'(lambda (x)
+ (or (,chk x)
+ (math-reject-arg x ',qual)))
+ ,var))
+ `((or (,chk ,var)
+ (math-reject-arg ,var ',qual)))))
+ (if (and (string-match "\\`not-\\(.*\\)\\'" qual-name)
+ (fboundp (setq chk (intern
+ (concat "math-"
+ (math-match-substring
+ qual-name 1))))))
+ (append rest
(if is-rest
- (list 'setq var
- (list 'mapcar (list 'quote chk) var))
- (list 'setq var (list chk var)))))
- (if (fboundp (setq chk (intern (concat "math-" qual-name))))
- (append rest
- (list
- (if is-rest
- (list 'mapcar
- (list 'function
- (list 'lambda '(x)
- (list 'or
- (list chk 'x)
- (list 'math-reject-arg
- 'x qqual))))
- var)
- (list 'or
- (list chk var)
- (list 'math-reject-arg var qqual)))))
- (if (and (string-match "\\`not-\\(.*\\)\\'" qual-name)
- (fboundp (setq chk (intern
- (concat "math-"
- (math-match-substring
- qual-name 1))))))
- (append rest
- (list
- (if is-rest
- (list 'mapcar
- (list 'function
- (list 'lambda '(x)
- (list 'and
- (list chk 'x)
- (list 'math-reject-arg
- 'x qqual))))
- var)
- (list 'and
- (list chk var)
- (list 'math-reject-arg var qqual)))))
- (error "Unknown qualifier `%s'" qual-name))))))))
+ `((mapcar #'(lambda (x)
+ (and (,chk x)
+ (math-reject-arg x ',qual)))
+ ,var))
+ `((and
+ (,chk ,var)
+ (math-reject-arg ,var ',qual)))))
+ (error "Unknown qualifier `%s'" qual-name))))))))
(defun math-do-arg-list-check (args is-opt is-rest)
(cond ((null args) nil)
(defun math-define-function-body (body env)
(let ((body (math-define-body body env)))
(if (math-body-refers-to body 'math-return)
- (list (cons 'catch (cons '(quote math-return) body)))
+ `((catch 'math-return ,@body))
body)))
;; The variable math-exp-env is local to math-define-body, but is
(provide 'calc-prog)
-;; arch-tag: 4c5a183b-c9e5-4632-bb3f-e41a764518b0
;;; calc-prog.el ends here