Go forward to Argument Qualifiers.
Go backward to Defining Simple Commands.
Go up to Lisp Definitions.
Defining New Stack-Based Commands
---------------------------------
To define a new computational command which takes and/or leaves
arguments on the stack, a special form of `interactive' clause is
used.
(interactive NUM TAG)
where NUM is an integer, and TAG is a string. The effect is to pop
NUM values off the stack, resimplify them by calling `calc-normalize',
and hand them to your function according to the function's argument
list. Your function may include `&optional' and `&rest' parameters,
so long as calling the function with NUM parameters is legal.
Your function must return either a number or a formula in a form
acceptable to Calc, or a list of such numbers or formulas. These
value(s) are pushed onto the stack when the function completes. They
are also recorded in the Calc Trail buffer on a line beginning with
TAG, a string of (normally) four characters or less. If you omit TAG
or use `nil' as a tag, the result is not recorded in the trail.
As an example, the definition
(defmath myfact (n)
"Compute the factorial of the integer at the top of the stack."
(interactive 1 "fact")
(if (> n 0)
(* n (myfact (1- n)))
(and (= n 0) 1)))
is a version of the factorial function shown previously which can be
used as a command as well as an algebraic function. It expands to
(defun calc-myfact ()
"Compute the factorial of the integer at the top of the stack."
(interactive)
(calc-slow-wrapper
(calc-enter-result 1 "fact"
(cons 'calcFunc-myfact (calc-top-list-n 1)))))
(defun calcFunc-myfact (n)
"Compute the factorial of the integer at the top of the stack."
(if (math-posp n)
(math-mul n (calcFunc-myfact (math-add n -1)))
(and (math-zerop n) 1)))
The `calc-slow-wrapper' function is a version of `calc-wrapper' that
automatically puts up a `Working...' message before the computation
begins. (This message can be turned off by the user with an `m w'
(`calc-working') command.)
The `calc-top-list-n' function returns a list of the specified number
of values from the top of the stack. It resimplifies each value by
calling `calc-normalize'. If its argument is zero it returns an empty
list. It does not actually remove these values from the stack.
The `calc-enter-result' function takes an integer NUM and string TAG
as described above, plus a third argument which is either a Calculator
data object or a list of such objects. These objects are resimplified
and pushed onto the stack after popping the specified number of values
from the stack. If TAG is non-`nil', the values being pushed are also
recorded in the trail.
Note that if `calcFunc-myfact' returns `nil' this represents "leave
the function in symbolic form." To return an actual empty list, in
the sense that `calc-enter-result' will push zero elements back onto
the stack, you should return the special value `'(nil)', a list
containing the single symbol `nil'.
The `interactive' declaration can actually contain a limited
Emacs-style code string as well which comes just before NUM and TAG.
Currently the only Emacs code supported is `"p"', as in
(defmath foo (a b &optional c)
(interactive "p" 2 "foo")
BODY)
In this example, the command `calc-foo' will evaluate the expression
`foo(a,b)' if executed with no argument, or `foo(a,b,n)' if executed
with a numeric prefix argument of `n'.
The other code string allowed is `"m"' (unrelated to the usual `"m"'
code as used with `defun'). It uses the numeric prefix argument as
the number of objects to remove from the stack and pass to the
function. In this case, the integer NUM serves as a default number of
arguments to be used when no prefix is supplied.