*************
* intro
*************

Quick introduction

	This is an interactive calculator which provides for easy large
	numeric calculations, but which also can be easily programmed
	for difficult or long calculations.  It can accept a command line
	argument, in which case it executes that single command and exits.
	Otherwise, it enters interactive mode.  In this mode, it accepts
	commands one at a time, processes them, and displays the answers.
	In the simplest case, commands are simply expressions which are
	evaluated.  For example, the following line can be input:

		3 * (4 + 1)

	and the calculator will print 15.

	The special '.' symbol (called dot), represents the result of the
	last command expression, if any.  This is of great use when a series
	of partial results are calculated, or when the output mode is changed
	and the last result needs to be redisplayed.  For example, the above
	result can be doubled by typing:

		. * 2

	and the calculator will print 30.

	For more complex calculations, variables can be used to save the
	intermediate results.  For example, the result of adding 7 to the
	previous result can be saved by typing:

		old = . + 7

	Functions can be used in expressions.  There are a great number of
	pre-defined functions.  For example, the following will calculate
	the factorial of the value of 'old':

		fact(old)

	and the calculator prints 13763753091226345046315979581580902400000000.
	Notice that numbers can be very large. (There is a practical limit
	of several thousand digits before calculations become too slow.)

	The calculator can calculate transcendental functions, and accept and
	display numbers in real or exponential format. For example, typing:

		config("display", 50)
		epsilon(1e-50)
		sin(1)

	prints "~.84147098480789650665250232163029899962256306079837".

	The calculator also knows about complex numbers, so that typing:

		(2+3i) * (4-3i)

	prints "17+6i".

*************
* overview
*************

			CALC - An arbitrary precision calculator.
				by David I. Bell


	This is a calculator program with arbitrary precision arithmetic.
	All numbers are represented as fractions with arbitrarily large
	numerators and denominators which are always reduced to lowest terms.
	Real or exponential format numbers can be input and are converted
	to the equivalent fraction.  Hex, binary, or octal numbers can be
	input by using numbers with leading '0x', '0b' or '0' characters.
	Complex numbers can be input using a trailing 'i', as in '2+3i'.
	Strings and characters are input by using single or double quotes.

	Commands are statements in a C-like language, where each input
	line is treated as the body of a procedure.  Thus the command
	line can contain variable declarations, expressions, labels,
	conditional tests, and loops.  Assignments to any variable name
	will automatically define that name as a global variable.  The
	other important thing to know is that all non-assignment expressions
	which are evaluated are automatically printed.  Thus, you can evaluate 
	an expression's value by simply typing it in.

	Many useful built-in mathematical functions are available.  Use
	the 'show builtins' command to list them.  You can also define
	your own functions by using the 'define' keyword, followed by a
	function declaration very similar to C.  Functions which only
	need to return a simple expression can be defined using an
	equals sign, as in the example 'define sc(a,b) = a^3 + b^3'.
	Variables in functions can be defined as either 'global', 'local',
	or 'static'.  Global variables are common to all functions and the
	command line, whereas local variables are unique to each function
	level, and are destroyed when the function returns.  Static variables
	are scoped within single input files, or within functions, and are
	never destroyed.  Variables are not typed at definition time, but
	dynamically change as they are used.  So you must supply the correct
	type of variable to those functions and operators which only work
	for a subset of types.

	By default, arguments to functions are passed by value (even
	matrices).  For speed, you can put an ampersand before any
	variable argument in a function call, and that variable will be
	passed by reference instead.  However, if the function changes
	its argument, the variable will change.  Arguments to built-in
	functions and object manipulation functions are always called
	by reference.  If a user-defined function takes more arguments
	than are passed, the undefined arguments have the null value.
	The 'param' function returns function arguments by argument
	number, and also returns the number of arguments passed.  Thus
	functions can be written to handle an arbitrary number of
	arguments.

	The mat statement is used to create a matrix.  It takes a
	variable name, followed by the bounds of the matrix in square
	brackets.  The lower bounds are zero by default, but colons can
	be used to change them.  For example 'mat foo[3, 1:10]' defines
	a two dimensional matrix, with the first index ranging from 0
	to 3, and the second index ranging from 1 to 10.  The bounds of
	a matrix can be an expression calculated at runtime.

	Lists of values are created using the 'list' function, and values can
	be inserted or removed from either the front or the end of the list.
	List elements can be indexed directly using double square brackets.

	The obj statement is used to create an object.  Objects are
	user-defined values for which user-defined routines are
	implicitly called to perform simple actions such as add,
	multiply, compare, and print. Objects types are defined as in
	the example 'obj complex {real, imag}', where 'complex' is the
	name of the object type, and 'real' and 'imag' are element
	names used to define the value of the object (very much like
	structures).  Variables of an object type are created as in the
	example 'obj complex x,y', where 'x' and 'y' are variables.
	The elements of an object are referenced using a dot, as in the
	example 'x.real'. All user-defined routines have names composed
	of the object type and the action to perform separated by an
	underscore, as in the example 'complex_add'.  The command 'show
	objfuncs' lists all the definable routines.  Object routines
	which accept two arguments should be prepared to handle cases
	in which either one of the arguments is not of the expected
	object type.

	These are the differences between the normal C operators and
	the ones defined by the calculator.  The '/' operator divides
	fractions, so that '7 / 2' evaluates to 7/2. The '//' operator
	is an integer divide, so that '7 // 2' evaluates to 3.  The '^'
	operator is a integral power function, so that 3^4 evaluates to
	81.  Matrices of any dimension can be treated as a zero based
	linear array using double square brackets, as in 'foo[[3]]'.
	Matrices can be indexed by using commas between the indices, as
	in foo[3,4].  Object and list elements can be referenced by
	using double square brackets.

	The print statement is used to print values of expressions.
	Separating values by a comma puts one space between the output
	values, whereas separating values by a colon concatenates the
	output values.  A trailing colon suppresses printing of the end
	of line.  An example of printing is 'print \"The square of\",
	x, \"is\", x^2\'.

	The 'config' function is used to modify certain parameters that
	affect calculations or the display of values.  For example, the
	output display mode can be set using 'config(\"mode\", type)',
	where 'type' is one of 'frac', 'int', 'real', 'exp', 'hex',
	'oct', or 'bin'.  The default output mode is real.  For the
	integer, real, or exponential formats, a leading '~' indicates
	that the number was truncated to the number of decimal places
	specified by the default precision.  If the '~' does not
	appear, then the displayed number is the exact value.

	The number of decimal places printed is set by using
	'config(\"display\", n)'.  The default precision for
	real-valued functions can be set by using 'epsilon(x)', where x
	is the required precision (such as 1e-50).

	There is a command stack feature so that you can easily
	re-execute previous commands and expressions from the terminal.
	You can also edit the current command before it is completed.
	Both of these features use emacs-like commands.

	Files can be read in by using the 'read filename' command.
	These can contain both functions to be defined, and expressions
	to be calculated.  Global variables which are numbers can be
	saved to a file by using the 'write filename' command.

*************
* help
*************

For more information while running calc, type  help  followed by one of the
following topics:

	topic		description
	-----		-----------
	intro		introduction to calc
	overview	overview of calc
	help		this file

	assoc		using associations
	builtin		builtin functions
	command		top level commands
	config		configuration parameters
	define		how to define functions
	environment	how environment variables effect calc
	expression	expression sequences
	file		using files
	history		command history
	interrupt	how interrupts are handled
	list		using lists
	mat		using matrices
	obj		user defined data types
	operator	math, relational, logic and variable access operators
	statement	flow control and declaration statements
	stdlib		description of some lib files shipped with calc
	types		builtin data types
	usage		how to invoke the calc command
	variable	variables and variable declarations

	bindings	input & history character bindings
	altbind		alternative input & history character bindings
	changes		recent changes to calc
	libcalc		using the arbitrary precision routines in a C program
	stdlib		standard calc library files and standards
	bugs		known bugs and mis-features
	todo		needed enhancements and wish list
	credit		who wrote calc and who helped

	full		all of the above

For example:

	help usage

will print the calc command usage information.  One can obtain calc help
without invoking any startup code by running calc as follows:

	calc -q help topic

where 'topic' is one of the topics listed above.

*************
* assoc
*************

Using associations

	Associations are special values that act like matrices, except
	that they are more general (and slower) than normal matrices.
	Unlike matrices, associations can be indexed by arbitrary values.
	For example, if 'val' was an association, you could do the following:

		val['hello'] = 11;
		val[4.5] = val['hello'];
		print val[9/2];

	and 11 would be printed.

	Associations are created by the 'assoc' function.  It takes no
	arguments, and simply returns an empty association.  You can then
	insert elements into the association by indexing the returned value
	as shown above.

	Associations are multi-dimensional.  You can index them using one to
	four dimensions as desired, and the elements with different numbers
	of dimensions will remain separated.  For example, 'val[3]' and
	'val[3,0]' can both be used in the same association and will be
	distinct elements.

	When references are made to undefined elements of an association,
	a null value is simply returned.  Therefore no bounds errors can
	occur when indexing an association.  Assignments of a null value
	to an element of an association does not delete the element, but
	a later reference to that element will return the null value as if
	the element was undefined.  Elements with null values are implicitly
	created on certain other operations which require an address to be
	taken, such as the += operator and using & in a function call.

	The elements of an association are stored in a hash table for
	quick access.  The index values are hashed to select the correct
	hash chain for a small sequential search for the element.  The hash
	table will be resized as necessary as the number of entries in
	the association becomes larger.

	The size function returns the number of elements in an association.
	This size will include elements with null values.

	Double bracket indexing can be used for associations to walk through
	the elements of the association.  The order that the elements are
	returned in as the index increases is essentially random.  Any
	change made to the association can reorder the elements, this making
	a sequential scan through the elements difficult.

	The search and rsearch functions can search for an element in an
	association which has the specified value.  They return the index
	of the found element, or a NULL value if the value was not found.

	Associations can be copied by an assignment, and can be compared
	for equality.  But no other operations on associations have meaning,
	and are illegal.

*************
* builtin
*************

Builtin functions

	There is a large number of built-in functions.  Many of the
	functions work on several types of arguments, whereas some only
	work for the correct types (e.g., numbers or strings).  In the
	following description, this is indicated by whether or not the
	description refers to values or numbers.  This display is generated
	by the 'show builtin' command.

	    Name      Args   Description

	    abs       1-2    absolute value within accuracy b
	    acos      1-2    arccosine of a within accuracy b
	    acosh     1-2    hyperbolic arccosine of a within accuracy b
	    append    2      append value to end of list
	    appr      1-2    approximate a with simpler fraction to within b
	    arg       1-2    argument (the angle) of complex number
	    asin      1-2    arcsine of a within accuracy b
	    asinh     1-2    hyperbolic arcsine of a within accuracy b
	    assoc     0      create new association array
	    atan      1-2    arctangent of a within accuracy b
	    atan2     2-3    angle to point (b,a) within accuracy c
	    atanh     1-2    hyperbolic arctangent of a within accuracy b
	    avg       1+     arithmetic mean of values
	    base      0-1    get/set default output base
	    bround    1-2    round value a to b number of binary places
	    btrunc    1-2    truncate a to b number of binary places
	    ceil      1      smallest integer greater than or equal to number
	    cfappr    1-2    approximate a within accuracy b using
				continued fractions
	    cfsim     1      simplify number using continued fractions
	    char      1      character corresponding to integer value
	    cmp       2      compare values returning -1, 0, or 1
	    comb      2      combinatorial number a!/b!(a-b)!
	    config    1-2    set or read configuration value
	    conj      1      complex conjugate of value
	    cos       1-2    cosine of value a within accuracy b
	    cosh      1-2    hyperbolic cosine of a within accuracy b
	    cp        2      cross product of two vectors
	    delete    2      delete element from list a at position b
	    den       1      denominator of fraction
	    det       1      determinant of matrix
	    digit     2      digit at specified decimal place of number
	    digits    1      number of digits in number
	    dp        2      dot product of two vectors
	    epsilon   0-1    set or read allowed error for real calculations
	    eval      1      evaluate expression from string to value
	    exp       1-2    exponential of value a within accuracy b
	    fcnt      2      count of times one number divides another
	    fib       1      Fibonacci number F(n)
	    frem      2      number with all occurrences of factor removed
	    fact      1      factorial
	    fclose    1      close file
	    feof      1      whether EOF reached for file
	    ferror    1      whether error occurred for file
	    fflush    1      flush output to file
	    fgetc     1      read next char from file
	    fgetline  1      read next line from file
	    files     0-1    return opened file or max number of opened files
	    floor     1      greatest integer less than or equal to number
	    fopen     2      open file name a in mode b
	    fprintf   2+     print formatted output to opened file
	    frac      1      fractional part of value
	    gcd       1+     greatest common divisor
	    gcdrem    2      a divided repeatedly by gcd with b
	    hash      1+     return non-negative hash value for one or
	                        more values
	    highbit   1      high bit number in base 2 representation
	    hmean     1+     harmonic mean of values
	    hypot     2-3    hypotenuse of right triangle within accuracy c
	    ilog      2      integral log of one number with another
	    ilog10    1      integral log of a number base 10
	    ilog2     1      integral log of a number base 2
	    im        1      imaginary part of complex number
	    insert    3      insert value c into list a at position b
	    int       1      integer part of value
	    inverse   1      multiplicative inverse of value
	    iroot     2      integer b'th root of a
	    isassoc   1      whether a value is an association
	    iseven    1      whether a value is an even integer
	    isfile    1      whether a value is a file
	    isint     1      whether a value is an integer
	    islist    1      whether a value is a list
	    ismat     1      whether a value is a matrix
	    ismult    2      whether a is a multiple of b
	    isnull    1      whether a value is the null value
	    isnum     1      whether a value is a number
	    isobj     1      whether a value is an object
	    isodd     1      whether a value is an odd integer
	    isqrt     1      integer part of square root
	    isreal    1      whether a value is a real number
	    isset     2      whether bit b of abs(a) (in base 2) is set
	    isstr     1      whether a value is a string
	    isrel     2      whether two numbers are relatively prime
	    issimple  1      whether value is a simple type
	    issq      1      whether or not number is a square
	    istype    2      whether the type of a is same as the type of b
	    jacobi    2      -1 => a is not quadratic residue mod b
			      1 => b is composite, or a is quad residue of b
	    lcm       1+     least common multiple
	    lcmfact   1      lcm of all integers up till number
	    lfactor   2      lowest prime factor of a in first b primes
	    list      0+     create list of specified values
	    ln        1-2    natural logarithm of value a within accuracy b
	    lowbit    1      low bit number in base 2 representation
	    ltol      1-2    leg-to-leg of unit right triangle (sqrt(1 - a^2))
	    matdim    1      number of dimensions of matrix
	    matfill   2-3    fill matrix with value b (value c on diagonal)
	    matmax    2      maximum index of matrix a dim b
	    matmin    2      minimum index of matrix a dim b
	    mattrans  1      transpose of matrix
	    max       1+     maximum value
	    meq       3      whether a and b are equal modulo c
	    min       1+     minimum value
	    minv      2      inverse of a modulo b
	    mmin      2      a mod b value with smallest abs value
	    mne       3      whether a and b are not equal modulo c
	    near      2-3    sign of (abs(a-b) - c)
	    norm      1      norm of a value (square of absolute value)
	    null      0      null value
	    num       1      numerator of fraction
	    ord       1      integer corresponding to character value
	    param     1      value of parameter n (or parameter count if n
				is zero)
	    perm      2      permutation number a!/(a-b)!
	    pfact     1      product of primes up till number
	    pi        0-1    value of pi accurate to within epsilon
	    places    1      places after decimal point (-1 if infinite)
	    pmod      3      mod of a power (a ^ b (mod c))
	    polar     2-3    complex value of polar coordinate (a * exp(b*1i))
	    poly      2+     (a1,a2,...,an,x) = a1*x^n+a2*x^(n-1)+...+an
	    pop       1      pop value from front of list
	    power     2-3    value a raised to the power b within accuracy c
	    ptest     2      probabilistic primality test
	    printf    1+     print formatted output to stdout
	    prompt    1      prompt for input line using value a
	    push      2      push value onto front of list
	    quomod    4      set c and d to quotient and remainder of a
				divided by b
	    rcin      2      convert normal number a to REDC number mod b
	    rcmul     3      multiply REDC numbers a and b mod c
	    rcout     2      convert REDC number a mod b to normal number
	    rcpow     3      raise REDC number a to power b mod c
	    rcsq      2      square REDC number a mod b
	    re        1      real part of complex number
	    remove    1      remove value from end of list
	    root      2-3    value a taken to the b'th root within accuracy c
	    round     1-2    round value a to b number of decimal places
	    rsearch   2-3    reverse search matrix or list for value b
				starting at index c
	    runtime   0      user mode cpu time in seconds
	    scale     2      scale value up or down by a power of two
	    search    2-3    search matrix or list for value b starting
				at index c
	    sgn       1      sign of value (-1, 0, 1)
	    sin       1-2    sine of value a within accuracy b
	    sinh      1-2    hyperbolic sine of a within accuracy b
	    size      1      total number of elements in value
	    sqrt      1-2    square root of value a within accuracy b
	    ssq       1+     sum of squares of values
	    str       1      simple value converted to string
	    strcat    1+     concatenate strings together
	    strlen    1      length of string
	    strprintf 1+     return formatted output as a string
	    substr    3      substring of a from position b for c chars
	    swap      2      swap values of variables a and b (can be dangerous)
	    tan       1-2    tangent of a within accuracy b
	    tanh      1-2    hyperbolic tangent of a within accuracy b
	    trunc     1-2    truncate a to b number of decimal places
	    xor       1+     logical xor

	The config function sets or reads the value of a configuration
	parameter.  The first argument is a string which names the parameter
	to be set or read.  If only one argument is given, then the current
	value of the named parameter is returned.  If two arguments are given,
	then the named parameter is set to the value of the second argument,
	and the old value of the parameter is returned.  Therefore you can
	change a parameter and restore its old value later.  The possible
	parameters are explained in the next section.

	The scale function multiplies or divides a number by a power of 2.
	This is used for fractional calculations, unlike the << and >>
	operators, which are only defined for integers.  For example,
	scale(6, -3) is 3/4.

	The quomod function is used to obtain both the quotient and remainder
	of a division in one operation.  The first two arguments a and b are
	the numbers to be divided.  The last two arguments c and d are two
	variables which will be assigned the quotient and remainder.  For
	nonnegative arguments, the results are equivalent to computing a//b
	and a%b.  If a is negative and the remainder is nonzero, then the
	quotient will be one less than a//b.  This makes the following three
	properties always hold:  The quotient c is always an integer.  The
	remainder d is always 0 <= d < b.  The equation a = b * c + d always
	holds.  This function returns 0 if there is no remainder, and 1 if
	there is a remainder.  For examples, quomod(10, 3, x, y) sets x to 3,
	y to 1, and returns the value 1, and quomod(-4, 3.14159, x, y) sets x
	to -2, y to 2.28318, and returns the value 1.

	The eval function accepts a string argument and evaluates the
	expression represented by the string and returns its value.
	The expression can include function calls and variable references.
	For example, eval("fact(3) + 7") returns 13.  When combined with
	the prompt function, this allows the calculator to read values from
	the user.  For example, x=eval(prompt("Number: ")) sets x to the
	value input by the user.

	The digit and isset functions return individual digits of a number,
	either in base 10 or in base 2, where the lowest digit of a number
	is at digit position 0.  For example, digit(5678, 3) is 5, and
	isset(0b1000100, 2) is 1.  Negative digit positions indicate places
	to the right of the decimal or binary point, so that for example,
	digit(3.456, -1) is 4.

	The ptest function is a primality testing function.  The first
	argument is the suspected prime to be tested.  The second argument
	is an iteration count.  The function returns 0 if the number is
	definitely not prime, and 1 is the number is probably prime.  The
	chance of a number which is probably prime being actually composite
	is less than 1/4 raised to the power of the iteration count.  For
	example, for a random number p, ptest(p, 10) incorrectly returns 1
	less than once in every million numbers, and you will probably never
	find a number where ptest(p, 20) gives the wrong answer.

	The functions rcin, rcmul, rcout, rcpow, and rcsq are used to
	perform modular arithmetic calculations for large odd numbers
	faster than the usual methods.  To do this, you first use the
	rcin function to convert all input values into numbers which are
	in a format called REDC format.  Then you use rcmul, rcsq, and
	rcpow to multiply such numbers together to produce results also
	in REDC format.  Finally, you use rcout to convert a number in
	REDC format back to a normal number.  The addition, subtraction,
	negation, and equality comparison between REDC numbers are done
	using the normal modular methods.  For example, to calculate the
	value 13 * 17 + 1 (mod 11), you could use:

		p = 11;
		t1 = rcin(13, p);
		t2 = rcin(17, p);
		t3 = rcin(1, p);
		t4 = rcmul(t1, t2, p);
		t5 = (t4 + t3) % p;
		answer = rcout(t5, p);

	The swap function exchanges the values of two variables without
	performing copies.  For example, after:

		x = 17;
		y = 19;
		swap(x, y);

	then x is 19 and y is 17.  This function should not be used to
	swap a value which is contained within another one.  If this is
	done, then some memory will be lost.  For example, the following
	should not be done:

		mat x[5];
		swap(x, x[0]);

	The hash function returns a relatively small non-negative integer
	for one or more input values.  The hash values should not be used
	across runs of the calculator, since the algorithms used to generate
	the hash value may change with different versions of the calculator.

	The base function allows one to specify how numbers should be
	printer.  The base function provides a numeric shorthand to the
	config("mode") interface.  With no args, base() will return the
	current mode.  With 1 arg, base(val) will set the mode according to
	the arg and return the previous mode.

	The following convention is used to declare modes:

		 base    config
		value    string

		   2	"binary"	binary fractions
		   8	"octal"		octal fractions
		  10	"real"		decimal floating point
		  16	"hex"		hexadecimal fractions
		 -10	"int"		decimal integer
		 1/3	"frac"		decimal fractions
		1e20	"exp"		decimal exponential
	
	For convenience, any non-integer value is assumed to mean "frac",
	and any integer >= 2^64 is assumed to mean "exp".

*************
* command
*************

Command sequence

	This is a sequence of any the following command formats, where
	each command is terminated by a semicolon or newline.  Long command
	lines can be extended by using a back-slash followed by a newline
	character.  When this is done, the prompt shows a double angle
	bracket to indicate that the line is still in progress.  Certain
	cases will automatically prompt for more input in a similar manner,
	even without the back-slash.  The most common case for this is when
	a function is being defined, but is not yet completed.

	Each command sequence terminates only on an end of file.  In
	addition, commands can consist of expression sequences, which are
	described in the next section.


	NOTE: Calc commands are in lower case.   UPPER case is used below
	      for emphasis only, and should be considered in lower case.


	DEFINE function(params) { body }
	DEFINE function(params) = expression
		This first form defines a full function which can consist
		of declarations followed by many statements which implement
		the function.

		The second form defines a simple function which calculates
		the specified expression value from the specified parameters.
		The expression cannot be a statement.  However, the comma
		and question mark operators can be useful.  Examples of
		simple functions are:

			define sumcubes(a, b) = a^3 + b^3;
			define pimod(a) = a % pi();

	HELP
		This displays a general help message.

	READ filename
		This reads definitions from the specified filename.
		The name can be quoted if desired.  The calculator
		uses the CALCPATH environment variable to search
		through the specified directories for the filename,
		similarly to the use of the PATH environment variable.
		If CALCPATH is not defined, then a default path which is
		usually ":/usr/local/lib/calc" is used (that is, the current 
		directory followed by a general calc library directory).  
		The ".cal" extension is defaulted for input files, so 
		that if "filename" is not found, then "filename.cal" is 
		then searched for.  The contents of the filename are 
		command sequences which can consist of expressions to 
		evaluate or functions to define, just like at the top 
		level command level.

	READ -once filename
    		This command acts like the regular READ expect that it 
		will ignore filename if is has been previously read.

		This command is particularly useful in a library that
		needs to read a 2nd library.  By using the READ -once
		command, one will not reread that 2nd library, nor will
		once risk entering into a infinite READ loop (where
		that 2nd library directly or indirectly does a READ of
		the first library).

	WRITE filename
		This writes the values of all global variables to the
		specified filename, in such a way that the file can be
		later read in order to recreate the variable values.
		For speed reasons, values are written as hex fractions.
		This command currently only saves simple types, so that
		matrices, lists, and objects are not saved.  Function
		definitions are also not saved.

	QUIT
		This leaves the calculator, when given as a top-level
		command.


	Also see the help topic:

		statement       flow control and declaration statements

*************
* config
*************

Configuration parameters

	Configuration parameters affect how the calculator performs certain
	operations, and affects all future calculations.  These parameters
	affect the accuracy of calculations, the displayed format of results,
	and which algorithms are used for calculations.  The parameters are
	read or set using the "config" built-in function.  The following
	parameters can be specified:

		"trace"		turns tracing on or off (for debugging).
		"display"	sets number of digits in prints.
		"epsilon"	sets error value for transcendentals.
		"maxprint"	sets maximum number of elements printed.
		"mode"		sets printout mode.
		"mul2"		sets size for alternative multiply.
		"sq2"		sets size for alternative squaring.
		"pow2"		sets size for alternate powering.
		"redc2"		sets size for alternate REDC.
		"tilde"		enable/disable printing of the roundoff '~'
		"tab"		enable/disable printing of leading tabs

	The use of the trace flag is for debugging, and its meaning may
	change in the future.  A value of 1 causes the calculator to print
	its internal opcodes as it executes functions.  A value of zero
	disables tracing again.

	Display specifies how many digits after the decimal point should
	be printed when printing real or exponential numbers.  The initial
	display value is 20.  This parameter does not affect the accuracy
	of a calculation, since it only has meaning when printing results.

	Epsilon specifies the required precision of calculations by
	setting the maximum allowed error for transcendental functions.
	The error is an absolute error value for many functions, but
	for some functions it is a relative error.  The initial value
	is 1e-20.  Functions which require an epsilon value accept an
	optional argument which overrides this default epsilon value for
	that single call.  The built-in function "epsilon" also can be
	used to read or set this value, and is provided for ease of use.

	Mode specifies how numbers should be printed.  Mode is a string
	value indicating the printout method.  The initial mode is "real".
	Possible modes are:

		"frac"		decimal fractions
		"int"		decimal integer
		"real"		decimal floating point
		"exp"		decimal exponential
		"hex"		hex fractions
		"oct"		octal fractions
		"bin"		binary fractions

	Maxprint specifies the maximum number of elements to be displayed
	when a matrix or list is printed.  The initial value is 16 elements.

	Mul2 and sq2 specify the sizes of numbers at which calc switches
	from its first to its second algorithm for multiplying and squaring.
	The first algorithm is the usual method of cross multiplying, which
	runs in a time of O(N^2).  The second method is a recursive and
	complicated method which runs in a time of O(N^1.585).  The argument
	for these parameters is the number of binary words at which the
	second algorithm begins to be used.  The minimum value is 2, and
	the maximum value is very large.  If 2 is used, then the recursive
	algorithm is used all the way down to single digits, which becomes
	slow since the recursion overhead is high.  If a number such as
	1000000 is used, then the recursive algorithm is never used, causing
	calculations for large numbers to slow down.  For a typical example
	on a 386, the two algorithms are about equal in speed for a value
	of 20, which is about 100 decimal digits.  A value of zero resets
	the parameter back to its default value.  Usually there is no need
	to change these parameters.

	Pow2 specifies the sizes of numbers at which calc switches from
	its first to its second algorithm for calculating powers modulo
	another number.  The first algorithm for calculating modular powers
	is by repeated squaring and multiplying and dividing by the modulus.
	The second method uses the REDC algorithm given by Peter Montgomery
	which avoids divisions.  The argument for pow2 is the size of the
	modulus at which the second algorithm begins to be used.

	Redc2 specifies the sizes of numbers at which calc switches from
	its first to its second algorithm when using the REDC algorithm.
	The first algorithm performs a multiply and a modular reduction
	together in one loop which runs in O(N^2).  The second algorithm
	does the REDC calculation using three multiplies, and runs in
	O(N^1.585).  The argument for redc2 is the size of the modulus at
	which the second algorithm begins to be used.

	Tilde controls the printing of a leading tilde ('~') in front
	of rounded values.  By default for integer, real, or exponential 
	formats, a leading '~' indicates that the number was truncated 
	to the number of decimal places specified by the default precision.
	The second config arg may be any truth value.

	Tab controls the printing of a tab before values.  By default,
	printed expressions proceeded by a tab.  This config option
	does not control the format of functions such as print or printf.
	The second config arg may be any truth value.

	The following are synonyms for true:

	    "on"   "yes"   "y"   "true"   "t"   "1"   any non-zero number

	The following are synonyms for false:

	    "off"  "no"    "n"   "false"  "f"   "0"   the number zero (0)

	Examples of setting some parameters are:

		config("mode", "exp");	    exponential output
		config("display", 50);	    50 digits of output
		epsilon(epsilon() / 8);	    3 bits more accuracy
		config("tilde", 0)	    disable roundoff tilde printing
		config("tab", "off")	    disable leading tab printing

*************
* define
*************

Function definitions

	Function definitions are introduced by the 'define' keyword.
	Other than this, the basic structure of a function is like in C.
	That is, parameters are specified for the function within parenthesis,
	the function body is introduced by a left brace, variables are
	declared for the function, statements implementing the function
	follow, and the function is ended with a right brace.

	There are some subtle differences, however.  The types of parameters
	and variables are not defined at compile time, but instead are typed
	at runtime.  Thus there is no definitions needed to distinguish
	between integers, fractions, complex numbers, matrices, and so on.
	Thus when declaring parameters for a function, only the name of
	the parameter is needed.  Thus there are never any declarations
	between the function parameter list and the body of the function.

	For example, the following function computes a factorial:

		define factorial(n)
		{
			local	ans;

			ans = 1;
			while (n > 1)
				ans *= n--;
			return ans;
		}

	If a function is very simple and just returns a value, then the
	function can be defined in shortened manner by using an equals sign
	in place of the left brace.  In this case, the function declaration
	is terminated by a newline character, and its value is the specified
	expression.  Statements such as 'if' are not allowed.  An optional
	semicolon ending the expression is allowed.  As an example, the
	average of two numbers could be defined as:

		define average(a, b) = (a + b) / 2;

	Functions can be defined which can be very complex.  These can be
	defined on the command line if desired, but editing of partial
	functions is not possible past a single line.  If an error is made
	on a previous line, then the function must be finished (with probable
	errors) and reentered from the beginning.  Thus for complicated
	functions, it is best to use an editor to create the function in a
	file, and then enter the calculator and read in the file containing
	the definition.

	The parameters of a function can be referenced by name, as in
	normal C usage, or by using the 'param' function.  This function
	returns the specified parameter of the function it is in, where
	the parameters are numbered starting from 1.  The total number
	of parameters to the function is returned by using 'param(0)'.
	Using this function allows you to implement varargs-like routines
	which can handle any number of calling parameters.  For example:

		define sc()
		{
			local s, i;

			s = 0;
			for (i = 1; i <= param(0); i++)
				s += param(i)^3;
			return s;
		}

	defines a function which returns the sum of the cubes of all it's
	parameters.

*************
* environment
*************

Environment variables

	CALCPATH

	    A :-separated list of directories used to search for
	    scripts filenames that do not begin with /, ./ or ~.

	    If this variable does not exist, a compiled value
	    is used.  Typically compiled in value is:

			.:./lib:~/lib:${LIBDIR}/calc
	
	    where ${LIBDIR} is usually:

			/usr/local/lib/calc

	    This value is used by the READ command.  It is an error
	    if no such readable file is found.
	
	
	CALCRC

	    On startup (unless -h or -q was given on the command
	    line), calc searches for files along the :-separated
	    $CALCRC environment variable.

	    If this variable does not exist, a compiled value
	    is used.  Typically compiled in value is:

			${LIBDIR}/startup:~/.calcrc
	
	    where ${LIBDIR} is usually:

			/usr/local/lib/calc

	    Missing files along the $CALCRC path are silently ignored.
	
	CALCBINDINGS

	    On startup (unless -h or -q was given on the command
	    line), calc reads key bindings from the filename specified
	    in the $CALCRC environment variable.  These key bindings
	    are used for command line editing and the command history.

	    If this variable does not exist, a compiled value is used.
	    Typically compiled in value is:

			${LIBDIR}/bindings
	
	    where ${LIBDIR} is usually:

			/usr/local/lib/calc

	    If the file could not be opened, or if standard input is not
	    a terminal, then calc will still run, but fancy command line
	    editing is disabled.

	HOME

	    This value is taken to be the home directory of the
	    current user.  It is used when files begin with '~/'.

	    If this variable does not exist, the home directory password 
	    entry of the current user is used.  If that information
	    is not available, '.' is used.
	
	PAGER

	    When invoking help, this environment variable is used
	    to display a help file.

	    If this variable does not exist, a compiled value
	    is used.  Typically compiled in value is something
	    such as 'more', 'less', 'pg' or 'cat'.
	
	SHELL

	    When a !-command is used, the program indicated by
	    this environment variable is used.

	    If this variable does not exist, a compiled value
	    is used.  Typically compiled in value is something
	    such as 'sh' is used.

*************
* expression
*************

Expression sequences

	This is a sequence of statements, of which expression statements
	are the commonest case.  Statements are separated with semicolons,
	and the newline character generally ends the sequence.  If any
	statement is an expression by itself, or is associated with an
	'if' statement which is true, then two special things can happen.
	If the sequence is executed at the top level of the calculator,
	then the value of '.' is set to the value of the last expression.
	Also, if an expression is a non-assignment, then the value of the
	expression is automatically printed if its value is not NULL.
	Some operations such as	pre-increment and plus-equals are also
	treated as assignments.

	Examples of this are the following:

	expression		sets '.' to		prints
	----------		-----------		------
	3+4			7			7
	2*4; 8+1; fact(3)	6			8, 9, and 6
	x=3^2			9			-
	if (3 < 2) 5; else 6	6			6
	x++			old x			-
	print fact(4)		-			24
	null()			null()			-

	Variables can be defined at the beginning of an expression sequence.
	This is most useful for local variables, as in the following example,
	which sums the square roots of the first few numbers:

	local s, i; s = 0; for (i = 0; i < 10; i++) s += sqrt(i); s

	If a return statement is executed in an expression sequence, then
	the result of the expression sequence is the returned value.  In
	this case, '.' is set to the value, but nothing is printed.

*************
* file
*************

Using files

	The calculator provides some functions which allow the program to
	read or write text files.  These functions use stdio internally,
	and the functions appear similar to some of the stdio functions.
	Some differences do occur, as will be explained here.

	Names of files are subject to ~ expansion just like the C or
	Korn shell.  For example, the file name:

		~/.rc.cal
	
	refers to the file '.rc.cal' under your home directory.  The
	file name:

		~chongo/.rc.cal

	refers to the a file 'rc.cal' under the home directory of 'chongo'.

	A file can be opened for either reading, writing, or appending.
	To do this, the 'fopen' function is used, which accepts a filename
	and an open mode, both as strings.  You use 'r' for reading, 'w'
	for writing, and 'a' for appending.  For example, to open the file
	'foo' for reading, the following could be used:

		fd = fopen('foo', 'r');

	If the open is unsuccessful, the numeric value of errno is returned.
	If the open is successful, a value of type 'file' will be returned.
	You can use the 'isfile' function to test the return value to see
	if the open succeeded.  You should assign the return value of fopen
	to a variable for later use.  File values can be copied to more than
	one variable, and using any of the variables with the same file value
	will produce the same results.

	If you overwrite a variable containing a file value or don't save the
	result of an 'fopen', the opened file still remains open.  Such 'lost'
	files can be recovered by using the 'files' function.  This function
	either takes no arguments or else takes one integer argument.  If no
	arguments are given, then 'files' returns the maximum number of opened
	files.  If an argument is given, then the 'files' function uses it as
	an index into an internal table of open files, and returns a value
	referring to one the open files.  If that entry in the table is not
	in use, then the null value is returned instead.  Index 0 always
	refers to standard input, index 1 always refers to standard output,
	and index 2 always refers to standard error.  These three files are
	already open by the calculator and cannot be closed.  As an example
	of using 'files', if you wanted to assign a file value which is
	equivalent to stdout, you could use:

		stdout = files(1);

	The 'fclose' function is used to close a file which had been opened.
	When this is done, the file value associated with the file remains
	a file value, but appears 'closed', and cannot be used in further
	file-related calls (except fclose) without causing errors.  This same
	action occurs to all copies of the file value.  You do not need to
	explicitly close all the copies of a file value.  The 'fclose'
	function returns the numeric value of errno if there had been an
	error using the file, or the null value if there was no error.

	File values can be printed.  When this is done, the filename of the
	opened file is printed inside of quote marks.  If the file value had
	been closed, then the null string is printed.  If a file value is the
	result of a top-level expression, then in addition to the filename,
	the open mode, file position, and possible EOF, error, and closed
	status is also displayed.

	File values can be used inside of 'if' tests.  When this is done,
	an opened file is TRUE, and a closed file is FALSE.  As an example
	of this, the following loop will print the names of all the currently
	opened non-standard files with their indexes, and then close them:

		for (i = 3; i < files(); i++) {
			if (files(i)) {
				print i, files(i);
				fclose(files(i));
			}
		}

	The functions to read from files are 'fgetline' and 'fgetc'.
	The 'fgetline' function accepts a file value, and returns the next
	input line from a file.  The line is returned as a string value, and
	does not contain the end of line character.  Empty lines return the
	null string.  When the end of file is reached, fgetline returns the
	null value.  (Note the distinction between a null string and a null
	value.)  If the line contained a numeric value, then the 'eval'
	function can then be used to convert the string to a numeric value.
	Care should be used when doing this, however, since eval will
	generate an error if the string doesn't represent a valid expression.
	The 'fgetc' function returns the next character from a file as a
	single character string.  It returns the null value when end of file
	is reached.

	The 'printf' and 'fprintf' functions are used to print results to a
	file (which could be stdout or stderr).  The 'fprintf' function
	accepts a file variable, whereas the 'printf' function assumes the
	use of 'files(1)' (stdout).  They both require a format string, which
	is used in almost the same way as in normal C.  The differences come
	in the interpretation of values to be printed for various formats.
	Unlike in C, where an unmatched format type and value will cause
	problems, in the calculator nothing bad will happen.  This is because
	the calculator knows the types of all values, and will handle them
	all reasonably.  What this means is that you can (for example), always
	use %s or %d in your format strings, even if you are printing a non-
	string or non-numeric value.  For example, the following is valid:

		printf("Two values are %d and %s\n", "fred", 4567);

	and will print "Two values are fred and 4567".

	Using particular format characters, however, is still useful if
	you wish to use width or precision arguments in the format, or if
	you wish to print numbers in a particular format.  The following
	is a list of the possible numeric formats:

		%d		print in currently defined numeric format
		%f		print as floating point
		%e		print as exponential
		%r		print as decimal fractions
		%x		print as hex fractions
		%o		print as octal fractions
		%b		print as binary fractions

	Note then, that using %d in the format makes the output configurable
	by using the 'config' function to change the output mode, whereas
	the other formats override the mode and force the output to be in
	the specified format.

	Using the precision argument will override the 'config' function
	to set the number of decimal places printed.  For example:

		printf("The number is %.100f\n", 1/3);

	will print 100 decimal places no matter what the display configuration
	value is set to.

	The %s and %c formats are identical, and will print out the string
	representation of the value.  In these cases, the precision argument
	will truncate the output the same way as in standard C.

	If a matrix or list is printed, then the output mode and precision
	affects the printing of each individual element.  However, field
	widths are ignored since these values print using multiple lines.
	Field widths are also ignored if an object value prints on multiple
	lines.

	The final file-related functions are 'fflush', 'ferror', and 'feof'.
	The 'fflush' function forces buffered output to a file.  The 'ferror'
	function returns nonzero if an error had occurred to a file.  The
	'feof' function returns nonzero if end of file has been reached
	while reading a file.

	The 'strprintf' function formats output similarly to 'printf',
	but the output is returned as a string value instead of being
	printed.

*************
* history
*************

Command history

	There is a command line editor and history mechanism built
	into calc, which is active when stdin is a terminal.  When
	stdin is not a terminal, then the command line editor is
	disabled.

	Lines of input to calc are always terminated by the return
	(or enter) key.  When the return key is typed, then the current
	line is executed and is also saved into a command history list
	for future recall.

	Before the return key is typed, the current line can be edited
	using emacs-like editing commands.  As examples, ^A moves to
	the beginning of the line, ^F moves forwards through the line,
	backspace removes characters from the line, and ^K kills the
	rest of the line.

	Previously entered commands can be recalled by using the history
	list.  The history list functions in a LRU manner, with no
	duplicated lines.  This means that the most recently entered
	lines are always at the end of the history list where they are
	easiest to recall.

	Typing <esc>h lists all of the commands in the command history
	and numbers the lines.  The most recently executed line is always
	number 1, the next most recent number 2, and so on.  The numbering
	for a particular command therefore changes as lines are entered.

	Typing a number at the beginning of a line followed by <esc>g
	will recall that numbered line.  So that for example, 2<esc>g
	will recall the second most recent line that was entered.

	The ^P and ^N keys move up and down the lines in the history list.
	If they attempt to go off the top or bottom of the list, then a
	blank line is shown to indicate this, and then they wrap around
	to the other end of the list.

	Typing a string followed by a ^R will search backwards through
	the history and recall the most recent command which begins
	with that string.

	Typing ^O inserts the current line at the end of the history list
	without executing it, and starts a new line.  This is useful to
	rearrange old history lines to become recent, or to save a partially
	completed command so that another command can be typed ahead of it.

	If your terminal has arrow keys which generate escape sequences
	of a particular kind (<esc>[A and so on), then you can use
	those arrow keys in place of the ^B, ^F, ^P, and ^N keys.

	The actual keys used for editing are defined in a bindings file,
	usually called /usr/local/lib/calc/bindings.  Changing the entries 
	in this file will change the key bindings used for editing.  If the 
	file is not readable, then a message will be output and command
	line editing is disabled.  In this case you can only edit each
	line as provided by the terminal driver in the operating system.

	A shell command can be executed by typing '!cmd', where cmd
	is the command to execute.  If cmd is not given, then a shell
	command level is started.

*************
* interrupt
*************

Interrupts

	While a calculation is in progress, you can generate the SIGINT
	signal, and the calculator will catch it.  At appropriate points
	within a calculation, the calculator will check that the signal
	has been given, and will abort the calculation cleanly.  If the
	calculator is in the middle of a large calculation, it might be
	a while before the interrupt has an effect.

	You can generate the SIGINT signal multiple times if necessary,
	and each time the calculator will abort the calculation at a more
	risky place within the calculation.  Each new interrupt prints a
	message of the form:

		[Abort level n]

	where n ranges from 1 to 3.  For n equal to 1, the calculator will
	abort calculations at the next statement boundary.  For n equal to 2,
	the calculator will abort calculations at the next opcode boundary.
	For n equal to 3, the calculator will abort calculations at the next
	lowest level arithmetic operation boundary.

	If a final interrupt is given when n is 3, the calculator will
	immediately abort the current calculation and longjmp back to the
	top level command level.  Doing this may result in corrupted data
	structures and unpredictable future behavior, and so should only
	be done as a last resort.  You are advised to quit the calculator
	after this has been done.

*************
* list
*************

Using lists

	Lists are a sequence of values which are doubly linked so that
	elements can be removed or inserted anywhere within the list.
	The function 'list' creates a list with possible initial elements.
	For example,

		x = list(4, 6, 7);

	creates a list in the variable x of three elements, in the order
	4, 6, and 7.

	The 'push' and 'pop' functions insert or remove an element from
	the beginning of the list.  The 'append' and 'remove' functions
	insert or remove an element from the end of the list.  The 'insert'
	and 'delete' functions insert or delete an element from the middle
	(or ends) of a list.  The functions which insert elements return
	the null value, but the functions which remove an element return
	the element as their value.  The 'size' function returns the number
	of elements in the list.

	Note that these functions manipulate the actual list argument,
	instead of returning a new list.  Thus in the example:

		push(x, 9);

	x becomes a list of four elements, in the order 9, 4, 6, and 7.
	Lists can be copied by assigning them to another variable.

	An arbitrary element of a linked list can be accessed by using the
	double-bracket operator.  The beginning of the list has index 0.
	Thus in the new list x above, the expression x[[0]] returns the
	value of the first element of the list, which is 9.  Note that this
	indexing does not remove elements from the list.

	Since lists are doubly linked in memory, random access to arbitrary
	elements can be slow if the list is large.  However, for each list
	a pointer is kept to the latest indexed element, thus relatively
	sequential accesses to the elements in a list will not be slow.

	Lists can be searched for particular values by using the 'search'
	and 'rsearch' functions.  They return the element number of the
	found value (zero based), or null if the value does not exist in
	the list.

*************
* mat
*************

Using matrices

	Matrices can have from 1 to 4 dimensions, and are indexed by a
	normal-sized integer.  The lower and upper bounds of a matrix can
	be specified at runtime.  The elements of a matrix are defaulted
	to zeroes, but can be assigned to be of any type.  Thus matrices
	can hold complex numbers, strings, objects, etc.  Matrices are
	stored in memory as an array so that random access to the elements
	is easy.

	Matrices are normally indexed using square brackets.  If the matrix
	is multi-dimensional, then an element can be indexed either by
	using multiple pairs of square brackets (as in C), or else by
	separating the indexes by commas.  Thus the following two statements
	reference the same matrix element:

		x = name[3][5];
		x = name[3,5];

	The double-square bracket operator can be used on any matrix to
	make references to the elements easy and efficient.  This operator
	bypasses the normal indexing mechanism, and treats the array as if
	it was one-dimensional and with a lower bound of zero.  In this
	indexing mode, elements correspond to the normal indexing mode where
	the rightmost index increases most frequently.  For example, when
	using double-square bracket indexing on a two-dimensional matrix,
	increasing indexes will reference the matrix elements left to right,
	row by row.  Thus in the following example, 'x' and 'y' are copied
	from the same matrix element:

		mat m[1:2, 1:3];
		x = m[2,1];
		y = m[[3]];

	There are functions which return information about a matrix.
	The 'size' functions returns the total number of elements.
	The 'matdim', 'matmin', and 'matmax' functions return the number
	of dimensions of a matrix, and the lower and upper index bounds
	for a dimension of a matrix.  For square matrices, the 'det'
	function calculates the determinant of the matrix.

	Some functions return matrices as their results.  These	functions
	do not affect the original matrix argument, but instead return
	new matrices.  For example, the 'mattrans' function returns the
	transpose of a matrix, and 'inverse' returns the inverse of a
	matrix.  So to invert a matrix called 'x', you could use:

		x = inverse(x);

	The 'matfill' function fills all elements of a matrix with the
	specified value, and optionally fills the diagonal elements of a
	square matrix with a different value.  For example:

		matfill(x,1);

	will fill any matrix with ones, and:

		matfill(x, 0, 1);

	will create an identity matrix out of any square matrix.  Note that
	unlike most matrix functions, this function does not return a matrix
	value, but manipulates the matrix argument itself.

	Matrices can be multiplied by numbers, which multiplies each element
	by the number.  Matrices can also be negated, conjugated, shifted,
	rounded, truncated, fractioned, and modulo'ed.  Each of these
	operations is applied to each element.

	Matrices can be added or multiplied together if the operation is
	legal.  Note that even if the dimensions of matrices are compatible,
	operations can still fail because of mismatched lower bounds.  The
	lower bounds of two matrices must either match, or else one of them
	must have a lower bound of zero.  Thus the following code:

		mat x[3:3];
		mat y[4:4];
		z = x + y;

	fails because the calculator does not have a way of knowing what
	the bounds should be on the resulting matrix.  If the bounds match,
	then the resulting matrix has the same bounds.  If exactly one of
	the lower bounds is zero, then the resulting matrix will have the
	nonzero lower bounds.  Thus means that the bounds of a matrix are
	preserved when operated on by matrices with lower bounds of zero.
	For example:

		mat x[3:7];
		mat y[5];
		z = x + y;

	will succeed and assign the variable 'z' a matrix whose
	bounds are 3-7.

	Vectors are matrices of only a single dimension.  The 'dp' and 'cp'
	functions calculate the dot product and cross product of a vector
	(cross product is only defined for vectors of size 3).

	Matrices can be searched for particular values by using the 'search'
	and 'rsearch' functions.  They return the element number of the
	found value (zero based), or null if the value does not exist in the
	matrix.  Using the element number in double-bracket indexing will
	then refer to the found element.

*************
* obj
*************

Using objects

	Objects are user-defined types which are associated with user-
	defined functions to manipulate them.  Object types are defined
	similarly to structures in C, and consist of one or more elements.
	The advantage of an object is that the user-defined routines are
	automatically called by the calculator for various operations,
	such as addition, multiplication, and printing.  Thus they can be
	manipulated by the user as if they were just another kind of number.

	An example object type is "surd", which represents numbers of the form

		a + b*sqrt(D),

	where D is a fixed integer, and 'a' and 'b' are arbitrary rational
	numbers.  Addition, subtraction, multiplication, and division can be
	performed on such numbers, and the result can be put unambiguously
	into the same form.  (Complex numbers are an example of surds, where
	D is -1.)

	The "obj" statement defines either an object type or an actual
	variable of that type.  When defining the object type, the names of
	its elements are specified inside of a pair of braces.  To define
	the surd object type, the following could be used:

		obj surd {a, b};

	Here a and b are the element names for the two components of the
	surd object.  An object type can be defined more than once as long
	as the number of elements and their names are the same.

	When an object is created, the elements are all defined with zero
	values.  A user-defined routine should be provided which will place
	useful values in the elements.  For example, for an object of type
	'surd', a function called 'surd' can be defined to set the two
	components as follows:

		define surd(a, b)
		{
			local x;

			obj surd x;
			x.a = a;
			x.b = b;
			return x;
		}

	When an operation is attempted for an object, user functions with
	particular names are automatically called to perform the operation.
	These names are created by concatenating the object type name and
	the operation name together with an underscore.  For example, when
	multiplying two objects of type surd, the function "surd_mul" is
	called.

	The user function is called with the necessary arguments for that
	operation.  For example, for "surd_mul", there are two arguments,
	which are the two numbers.  The order of the arguments is always
	the order of the binary operands.  If only one of the operands to
	a binary operator is an object, then the user function for that
	object type is still called.  If the two operands are of different
	object types, then the user function that is called is the one for
	the first operand.

	The above rules mean that for full generality, user functions
	should detect that one of their arguments is not of its own object
	type by using the 'istype' function, and then handle these cases
	specially.  In this way, users can mix normal numbers with object
	types.  (Functions which only have one operand don't have to worry
	about this.)  The following example of "surd_mul" demonstrates how
	to handle regular numbers when used together with surds:

		define surd_mul(a, b)
		{
			local x;

			obj surd x;
			if (!istype(a, x)) {	
				/* a not of type surd */
				x.a = b.a * a;
				x.b = b.b * a;
			} else if (!istype(b, x)) {
				/* b not of type surd */
				x.a = a.a * b;
				x.b = a.b * b;
			} else {			
				/* both are surds */
				x.a = a.a * b.a + D * a.b * b.b;
				x.b = a.a * b.b + a.b * b.a;
			}
			if (x.b == 0)
				return x.a;	/* normal number */
			return x;		/* return surd */
		}

	In order to print the value of an object nicely, a user defined
	routine can be provided.  For small amounts of output, the print
	routine should not print a newline.  Also, it is most convenient
	if the printed object looks like the call to the creation routine.
	For output to be correctly collected within nested output calls,
	output should only go to stdout.  This means use the 'print'
	statement, the 'printf' function, or the 'fprintf' function with
	'files(1)' as the output file.  For example, for the "surd" object:

		define surd_print(a)
		{
			print "surd(" : a.a : "," : a.b : ")" : ;
		}

	It is not necessary to provide routines for all possible operations
	for an object, if those operations can be defaulted or do not make
	sense for the object.  The calculator will attempt meaningful
	defaults for many operations if they are not defined.  For example,
	if 'surd_square' is not defined to square a number, then 'surd_mul'
	will be called to perform the squaring.  When a default is not
	possible, then an error will be generated.

	Please note: Arguments to object functions are always passed by
	reference (as if an '&' was specified for each variable in the call).
	Therefore, the function should not modify the parameters, but should
	copy them into local variables before modifying them.  This is done
	in order to make object calls quicker in general.

	The double-bracket operator can be used to reference the elements
	of any object in a generic manner.  When this is done, index 0
	corresponds to the first element name, index 1 to the second name,
	and so on.  The 'size' function will return the number of elements
	in an object.

	The following is a list of the operations possible for objects.
	The 'xx' in each function name is replaced with the actual object
	type name.  This table is displayed by the 'show objfuncs' command.

		Name	Args	Comments

		xx_print    1	print value, default prints elements
		xx_one      1	multiplicative identity, default is 1
		xx_test     1	logical test (false,true => 0,1), 
				    default tests elements
		xx_add      2	
		xx_sub      2	subtraction, default adds negative
		xx_neg      1	negative
		xx_mul      2	
		xx_div      2	non-integral division, default multiplies 
				    by inverse
		xx_inv      1	multiplicative inverse
		xx_abs      2	absolute value within given error
		xx_norm     1	square of absolute value
		xx_conj     1	conjugate
		xx_pow      2	integer power, default does multiply, 
				    square, inverse
		xx_sgn      1	sign of value (-1, 0, 1)
		xx_cmp      2	equality (equal,non-equal => 0,1), 
				    default tests elements
		xx_rel      2	inequality (less,equal,greater => -1,0,1)
		xx_quo      2	integer quotient
		xx_mod      2	remainder of division
		xx_int      1	integer part
		xx_frac     1	fractional part
		xx_inc      1	increment, default adds 1
		xx_dec      1	decrement, default subtracts 1
		xx_square   1	default multiplies by itself
		xx_scale    2	multiply by power of 2
		xx_shift    2	shift left by n bits (right if negative)
		xx_round    2	round to given number of decimal places
		xx_bround   2	round to given number of binary places
		xx_root     3	root of value within given error
		xx_sqrt     2	square root within given error


	Also see the library files:

		dms.cal
		mod.cal
		poly.cal
		quat.cal
		surd.cal

*************
* operator
*************

Operators

	The operators are similar to C, but the precedence of some of
	the operators differs.  In addition, there are several additional
	operators, and some C operators are missing.  The following list
	gives the operators arranged in order of precedence, from the
	least tightly binding to the most tightly binding:

	,	Comma operator.
		For situations in which a comma is used for another purpose
		(function arguments, array indexing, and the print statement),
		parenthesis must be used around the comma operator.

	? :	Conditional value.
		a ? b : c  returns b if a is nonzero, c otherwise.
		Thus it is equivalent to: if (a) return b; else return c;.
		All that is required of the arguments in this function
		is that the is-it-nonzero test is meaningful for a.

	=  +=  -=  *=  /=  %=  //=  &=  |=  <<=  >>=  ^=  **=
		Assignments.

	||	Logical OR.
		Unlike C, the result is the first non-zero expression or 0,
		instead of just 0 or 1.  Thus a || b is equivalent to
		a ? a : b.

	&&	Logical AND.
		Unlike C, the result is the last expression or 0,
		instead of just 0 or 1.  Thus a && b is equivalent to
		!a ? 0 : (!b ? 0 : b).

	==  !=  <=  >=  <  >
		Relations.

	+  -
		Binary plus and minus.

	*  /  //  %
		Multiply, divide. and modulo.
		Please Note: The '/' operator is a fractional divide,
		whereas the '//' is an integral divide.  Thus think of '/'
		as division of real numbers, and think of '//' as division
		of integers (e.g., 8 / 3 is 8/3 whereas 8 // 3 is 2).
		The '%' is integral or fractional modulus (e.g., 11%4 is 3,
		and 10%pi() is ~.575222).

	|	Bitwise OR.
		In a | b, both a and b are to be real integers;
		the signs of a and b are ignored, i.e.
		a | b = abs(a) | abs(b) and the result will
		be a non-negative integer.

	&	Bitwise AND.
		In a & b, both a and b are to be real integers;
		the signs of a and b are ignored as for a | b.

	^  **  <<  >>
		Powers and shifts.
		The '^' and '**' are both exponentiation, e.g. 2^3
		returns 8, 2^-3 returns .125.  In a ^ b, b has to be
		an integer and if a is zero, nonnegative.  0^0 returns
		the value 1.

		For the shift operators both arguments are to be
		integers, or if the first is complex, it is to have
		integral real and imaginary parts.  Changing the
		sign of the second argument reverses the shift, e.g.
		a >> -b = a << b.  The result has the same sign as
		the first argument except that a nonzero value is
		reduced to zero by a sufficiently long shift to the
		right.  These operators associate right to left,
		e.g.  a << b ^ c = a << (b ^ c).

	+  -  !
		Unary operators.
		The '!' is the logical NOT operator: !a returns 0 if
		a is nonzero, and 1 if a is zero, i.e. it is
		equivalent to a ? 0 : 1.  Be careful about
		using this as the first character of a top level command,
		since it is also used for executing shell commands.

	++  --
		Pre or post incrementing or decrementing.
		These are applicable only to variables.

	[ ]  [[ ]]  .  ( )
		Indexing, double-bracket indexing, element references,
		and function calls.  Indexing can only be applied to matrices,
		element references can only be applied to objects, but
		double-bracket indexing can be applied to matrices, objects,
		or lists.

	variables  constants  .  ( )
		These are variable names and constants, the special '.' symbol,
		or a parenthesized expression.  Variable names begin with a
		letter, but then can contain letters, digits, or underscores.
		Constants are numbers in various formats, or strings inside
		either single or double quote marks.


	The most significant difference from the order of precedence in
	C is that | and & have higher precedence than ==, +, -, *, / and %.
	For example, in C a == b | c * d is interpreted as:

		(a == b) | (c * d)

	and calc it is:

		a == ((b | c) * d)


	Most of the operators will accept any real or complex numbers
	as arguments.  The exceptions are:

	/  //  %
		Second argument must be nonzero.

	^
		The exponent must be an integer.  When raising zero
		to a power, the exponent must be non-negative.

	|  &
		Both both arguments must be integers.

	<<  >>
		The shift amount must be an integer.  The value being
		shifted must be an integer or a complex number with
		integral real and imaginary parts.

*************
* statement
*************

Statements

	Statements are very much like C statements.  Most statements act
	identically to those in C, but there are minor differences and
	some additions.  The following is a list of the statement types,
	with explanation of the non-C statements.  In this list, upper
	case words identify the keywords which are actually in lower case.
	Statements are generally terminated with semicolons, except if the
	statement is the compound one formed by matching braces.  Various
	expressions are optional and may be omitted (as in RETURN).


	NOTE: Calc commands are in lower case.   UPPER case is used below
	      for emphasis only, and should be considered in lower case.


	IF (expr) statement
	IF (expr) statement ELSE statement
	FOR (optionalexpr ; optionalexpr ; optionalexpr) statement
	WHILE (expr) statement
	DO statement WHILE (expr)
	CONTINUE
	BREAK
	GOTO label
		These all work like in normal C.

	RETURN optionalexpr
		This returns a value from a function.  Functions always
		have a return value, even if this statement is not used.
		If no return statement is executed, or if no expression
		is specified in the return statement, then the return
		value from the function is the null type.

	SWITCH (expr) { caseclauses }
		Switch statements work similarly to C, except for the
		following.  A switch can be done on any type of value,
		and the case statements can be of any type of values.
		The case statements can also be expressions calculated
		at runtime.  The calculator compares the switch value
		with each case statement in the order specified, and
		selects the first case which matches.  The default case
		is the exception, and only matches once all other cases
		have been tested.

	{ statements }
		This is a normal list of statements, each one ended by
		a semicolon.  Unlike the C language, no declarations are
		permitted within an inner-level compound statement.
		Declarations are only permitted at the beginning of a
		function definition, or at the beginning of an expression
		sequence.

	MAT variable [dimension] [dimension] ...
	MAT variable [dimension, dimension, ...]
	MAT variable [] = { value, ... }
		This creates a matrix variable with the specified dimensions.
		Matrices can have from 1 to 4 dimensions.  When specifying
		multiple dimensions, you can use either the standard C syntax,
		or else you can use commas for separating the dimensions.
		For example, the following two statements are equivalent,
		and so will create the same two dimensional matrix:

			mat foo[3][6];
			mat foo[3,6];

		By default, each dimension is indexed starting at zero,
		as in normal C, and contains the specified number of
		elements.  However, this can be changed if a colon is
		used to separate two values.  If this is done, then the
		two values become the lower and upper bounds for indexing.
		This is convenient, for example, to create matrices whose
		first row and column begin at 1.  Examples of matrix
		definitions are:

			mat x[3]	one dimension, bounds are 0-2
			mat foo[4][5]	two dimensions, bounds are 0-3 and 0-4
			mat a[-7:7]	one dimension, bounds are (-7)-7
			mat s[1:9,1:9]	two dimensions, bounds are 1-9 and 1-9

		Note that the MAT statement is not a declaration, but is
		executed at runtime.  Within a function, the specified
		variable must already be defined, and is just converted to
		a matrix of the specified size, and all elements are set
		to the value of zero.  For convenience, at the top level
		command level, the MAT command automatically defines a
		global variable of the specified name if necessary.

		Since the MAT statement is executed, the bounds on the
		matrix can be full expressions, and so matrices can be
		dynamically allocated.  For example:

			size = 20;
			mat data[size*2];

		allocates a matrix which can be indexed from 0 to 39.

		Initial values for the elements of a matrix can be specified
		by following the bounds information with an equals sign and
		then a list of values enclosed in a pair of braces.  Even if
		the matrix has more than one dimension, the elements must be
		specified as a linear list.  If too few values are specified,
		the remaining values are set to zero.  If too many values are
		specified, a runtime error will result.  Examples of some
		initializations are:

			mat table1[5] = {77, 44, 22};
			mat table2[2,2] = {1, 2, 3, 4};

		When an initialization is done, the bounds of the matrix
		can optionally be left out of the square brackets, and the
		correct bounds (zero based) will be set.  This can only be
		done for one-dimensional matrices.  An example of this is:

			mat fred[] = {99, 98, 97};

		The MAT statement can also be used in declarations to set
		variables as being matrices from the beginning.  For example:

			local mat temp[5];
			static mat strtable[] = {"hi", "there", "folks");

	OBJ type { elementnames } optionalvariables
	OBJ type variable

		These create a new object type, or create one or more
		variables of the specified type.  For this calculator,
		an object is just a structure which is implicitly acted
		on by user defined routines.  The user defined routines
		implement common operations for the object, such as plus
		and minus, multiply and divide, comparison and printing.
		The calculator will automatically call these routines in
		order to perform many operations.
	
		To create an object type, the data elements used in
		implementing the object are specified within a pair
		of braces, separated with commas.  For example, to
		define an object will will represent points in 3-space,
		whose elements are the three coordinate values, the
		following could be used:
	
			obj point {x, y, z};
	
		This defines an object type called point, whose elements
		have the names x, y, and z.  The elements are accessed
		similarly to structure element accesses, by using a period.
		For example, given a variable 'v' which is a point object,
		the three coordinates of the point can be referenced by:

			v.x
			v.y
			v.z

		A particular object type can only be defined once, and
		is global throughout all functions.  However, different
		object types can be used at the same time.

		In order to create variables of an object type, they
		can either be named after the right brace of the object
		creation statement, or else can be defined later with
		another obj statement.  To create two points using the
		second (and most common) method, the following is used:

			obj point p1, p2;	

		This statement is executed, and is not a declaration.
		Thus within a function, the variables p1 and p2 must have
		been previously defined, and are just changed to be the
		new object type.  For convenience, at the top level command
		level, object variables are automatically defined as being
		global when necessary.

		Initial values for an object can be specified by following
		the variable name by an equals sign and a list of values
		enclosed in a pair of braces.  For example:

			obj point pt = {5, 6};

		The OBJ statement can also be used in declarations to set
		variables as being objects from the beginning.  If multiple
		variables are specified, then each one is defined as the
		specified object type.  Examples of declarations are:

			local obj point temp1;
			static obj point temp2 = {4, 3};
			global obj point p1, p2, p3;

	EXIT string
	QUIT string

		This command is used in two cases.  At the top command
		line level, quit will exit from the calculator.  This
		is the normal way to leave the calculator.  In any other
		use, quit will abort the current calculation as if an
		error had occurred.  If a string is given, then the string
		is printed as the reason for quitting, otherwise a general
		quit message is printed.  The routine name and line number
		which executed the quit is also printed in either case.

		Quit is useful when a routine detects invalid arguments,
		in order to stop a calculation cleanly.  For example,
		for a square root routine, an error can be given if the
		supplied parameter was a negative number, as in:

			define mysqrt(n)
			{
				if (n < 0)
					quit "Negative argument";
				...
			}

		Exit is an alias for quit.


	PRINT exprs

		For interactive expression evaluation, the values of all
		typed-in expressions are automatically displayed to the
		user.  However, within a function or loop, the printing of
		results must be done explicitly.  This can be done using
		the 'printf' or 'fprintf' functions, as in standard C, or
		else by using the built-in 'print' statement.  The advantage
		of the print statement is that a format string is not needed.
		Instead, the given values are simply printed with zero or one
		spaces between each value.

		Print accepts a list of expressions, separated either by
		commas or colons.  Each expression is evaluated in order
		and printed, with no other output, except for the following
		special cases.  The comma which separates expressions prints
		a single space, and a newline is printed after the last
		expression unless the statement ends with a colon.  As
		examples:

			print 3, 4;		prints "3 4" and newline.
			print 5:;		prints "5" with no newline.
			print 'a' : 'b' , 'c';	prints "ab c" and newline.
			print;			prints a newline.

		For numeric values, the format of the number depends on the
		current "mode" configuration parameter.  The initial mode
		is to print real numbers, but it can be changed to other
		modes such as exponential, decimal fractions, or hex.

		If a matrix or list is printed, then the elements contained
		within the matrix or list will also be printed, up to the
		maximum number specified by the "maxprint" configuration
		parameter.  If an element is also a matrix or a list, then
		their values are not recursively printed.  Objects are printed
		using their user-defined routine.  Printing a file value
		prints the name of the file that was opened.


	SHOW item

		This command displays some information.
		The following is a list of the various items:

			builtins	built in functions
			globals		global variables
			functions	user-defined functions
			objfuncs	possible object functions
			memory		memory usage

		Singular forms of item may also be used.  The following 
		statement are the same:

			show builtins
			show builtin
	

	Also see the help topic:

		command         top level commands

*************
* types
*************

Builtin types

	The calculator has the following built-in types.

	null value
		This is the undefined value type.  The function 'null'
		returns this value.  Functions which do not explicitly
		return a value return this type.  If a function is called
		with fewer parameters than it is defined for, then the
		missing parameters have the null type.  The null value is
		false if used in an IF test.

	rational numbers
		This is the basic data type of the calculator.
		These are fractions whose numerators and denominators
		can be arbitrarily large.  The fractions are always
		in lowest terms.  Integers have a denominator of 1.
		The numerator of the number contains the sign, so that
		the denominator is always positive.  When a number is
		entered in floating point or exponential notation, it is
		immediately converted to the appropriate fractional value.
		Printing a value as a floating point or exponential value
		involves a conversion from the fractional representation.

		Numbers are stored in binary format, so that in general,
		bit tests and shifts are quicker than multiplies and divides.
		Similarly, entering or displaying of numbers in binary,
		octal, or hex formats is quicker than in decimal.  The
		sign of a number does not affect the bit representation
		of a number.

	complex numbers
		Complex numbers are composed of real and imaginary parts,
		which are both fractions as defined above.  An integer which
		is followed by an 'i' character is a pure imaginary number.
		Complex numbers such as "2+3i" when typed in, are processed
		as the sum of a real and pure imaginary number, resulting
		in the desired complex number.  Therefore, parenthesis are
		sometimes necessary to avoid confusion, as in the two values:

			1+2i ^2		(which is -3)
			(1+2i) ^2	(which is -3+4i)

		Similar care is required when entering fractional complex
		numbers.  Note the differences below:

			3/4i		(which is -(3/4)i)
			3i/4		(which is (3/4)i)

		The imaginary unit itself is input using "1i".

	strings
		Strings are a sequence of zero or more characters.
		They are input using either of the single or double
		quote characters.  The quote mark which starts the
		string also ends it.  Various special characters can
		also be inserted using back-slash.  Example strings:

			"hello\n"
			"that's all"
			'lots of """"'
			'a'
			""

		There is no distinction between single character and
		multi-character strings.  The 'str' and 'ord' functions
		will convert between a single character string and its
		numeric value.  The 'str' and 'eval' functions will
		convert between longer strings and the corresponding
		numeric value (if legal).  The 'strcat', 'strlen', and
		'substr' functions are also useful.

	matrices
		These are one to four dimensional matrices, whose minimum
		and maximum bounds can be specified at runtime.  Unlike C,
		the minimum bounds of a matrix do not have to start at 0.
		The elements of a matrix can be of any type.  There are
		several built-in functions for matrices.  Matrices are
		created using the 'mat' statement.

	associations
		These are one to four dimensional matrices which can be
		indexed by arbitrary values, instead of just integers.
		These are also known as associative arrays.  The elements of
		an association can be of any type.  Very few operations are
		permitted on an association except for indexing.  Associations
		are created using the 'assoc' function.

	lists
		These are a sequence of values, which are linked together
		so that elements can be easily be inserted or removed
		anywhere in the list.  The values can be of any type.
		Lists are created using the 'list' function.

	files
		These are text files opened using stdio.  Files may be opened
		for sequential reading, writing, or appending.  Opening a
		file using the 'fopen' function returns a value which can
		then be used to perform I/O to that file.  File values can
		be copied by normal assignments between variables, or by
		using the result of the 'files' function.  Such copies are
		indistinguishable from each other.

*************
* usage
*************

Calc command line

	Calc has the following command line:

		calc [-h] [-q] [calc_command ...]

		-h	print a help message  (equivalent to the
			help command)

		-q	By default, calc executes each file specified
			in the :-separated list found in the environment
			variable $CALCRC.  If $CALCRC does not exist,
			an internal default is used.

	If some calc_commands arguments are given on the command line,
	calc executes these commands and then exists.  If no command
	line arguments are given, calc prompts and reads commands
	from standard input.

*************
* variable
*************

Variable declarations

	Variables can be declared as either being global, local, or static.
	Global variables are visible to all functions and on the command
	line, and are permanent.  Local variables are visible only within
	a single function or command sequence.  When the function or command
	sequence returns, the local variables are deleted.  Static variables
	are permanent like global variables, but are only visible within the
	same input file or function where they are defined.

	To declare one or more variables, the 'local', 'global', or 'static'
	keywords are used, followed by the desired list of variable names,
	separated by commas.  The definition is terminated with a semicolon.
	Examples of declarations are:

		local	x, y, z;
		global	fred;
		local	foo, bar;
		static	var1, var2, var3;

	Variables may have initializations applied to them.  This is done
	by following the variable name by an equals sign and an expression.
	Global and local variables are initialized each time that control
	reaches them (e.g., at the entry to a function which contains them).
	Static variables are initialized once only, at the time that control
	first reaches them (but in future releases the time of initialization
	may change).  Unlike in C, expressions for static variables may
	contain function calls and refer to variables.  Examples of such
	initializations are:

		local	a1 = 7, a2 = 3;
		static	b = a1 + sin(a2);

	Within function declarations, all variables must be defined.
	But on the top level command line, assignments automatically define
	global variables as needed.  For example, on the top level command
	line, the following defines the global variable x if it had not
	already been defined:

		x = 7

	The static keyword may be used at the top level command level to
	define a variable which is only accessible interactively, or within
	functions defined interactively.

	Variables have no fixed type, thus there is no need or way to
	specify the types of variables as they are defined.  Instead, the
	types of variables change as they are assigned to or are specified
	in special statements such as 'mat' and 'obj'.  When a variable is
	first defined using 'local', 'global', or 'static', it has the
	value of zero.

	If a procedure defines a local or static variable name which matches
	a global variable name, or has a parameter name which matches a
	global variable name, then the local variable or parameter takes
	precedence within that procedure, and the global variable is not
	directly accessible.

	The MAT and OBJ keywords may be used within a declaration statement
	in order to initially define variables as that type.  Initialization
	of these variables are also allowed.  Examples of such declarations
	are:

		static mat table[3] = {5, 6, 7};
		local obj point p1, p2;

	There are no pointers in the calculator language, thus all
	arguments to user-defined functions are normally passed by value.
	This is true even for matrices, strings, and lists.  In order
	to circumvent this, the '&' operator is allowed before a variable
	when it is an argument to a function.  When this is done, the
	address of the variable is passed to the function instead of its
	value.  This is true no matter what the type of the variable is.
	This allows for fast calls of functions when the passed variable
	is huge (such as a large array).  However, the passed variable can
	then be changed by the function if the parameter is assigned into.
	The function being called does not need to know if the variable
	is being passed by value or by address.

	Built-in functions and object functions always accept their
	arguments as addresses, thus there is no need to use '&' when
	calling built-in functions.

*************
* bindings
*************

# Default key bindings for calc line editing functions

map	base-map
default	insert-char
^@	set-mark
^A	start-of-line
^B	backward-char
^D	delete-char
^E	end-of-line
^F	forward-char
^H	backward-kill-char
^J	new-line
^K	kill-line
^L	refresh-line
^M	new-line
^N	forward-history
^O	save-line
^P	backward-history
^R	reverse-search
^T	swap-chars
^U	flush-input
^V	quote-char
^W	kill-region
^Y	yank
^?	backward-kill-char
^[	ignore-char	esc-map

map	esc-map
default	ignore-char	base-map
G	start-of-line
H	backward-history
P	forward-history
K	backward-char
M	forward-char
O	end-of-line
S	delete-char
g	goto-line
s	backward-word
t	forward-word
d	forward-kill-word
u	uppercase-word
l	lowercase-word
h	list-history
^[	flush-input
[	arrow-key

*************
* altbind
*************

# Alternate key bindings for calc line editing functions

map	base-map
default	insert-char
^@	set-mark
^A	start-of-line
^B	backward-char
^D	quit
^E	end-of-line
^F	forward-char
^H	backward-kill-char
^J	new-line
^K	kill-line
^L	refresh-line
^M	new-line
^N	forward-history
^O	save-line
^P	backward-history
^R	reverse-search
^T	swap-chars
^U	flush-input
^V	quote-char
^W	kill-region
^Y	yank
^?	delete-char
^[	ignore-char	esc-map

map	esc-map
default	ignore-char	base-map
G	start-of-line
H	backward-history
P	forward-history
K	backward-char
M	forward-char
O	end-of-line
S	delete-char
g	goto-line
s	backward-word
t	forward-word
d	forward-kill-word
u	uppercase-word
l	lowercase-word
h	list-history
^[	flush-input
[	arrow-key

*************
* changes
*************

Following is the change from calc version 2.9.2 to 2.9.3t6:

    WARNING: This patch is an unofficial alpha test patch by chongo@toad.com
	     (Landon Curt Noll) which as not been fully reviewed.  Blame
	     chongo for any problems this patch may cause!  The paranoid may
	     want to use 2.9.2 or wait for 2.9.4.

    Calc can now compile on OSF/1, SGI and IBM RS6000 systems.

    A number of systems that have both <varargs.h> and <stdarg.h> do
    not correctly implement both types.  On some System V, MIPS and DEC
    systems, vsprintf() and <stdarg.h> do not mix.  While calc will
    pass the regression test, use of undefined variables will cause
    problems.  The Makefile has been modified to look for this problem
    and work around it.

    Added randmprime.cal which find a prime of the form h*2^n-1 >= 2^x
    for some given x.  The initial search points for 'h' and 'n'
    are selected by a cryptographic pseudo-random generator.

    The library script nextprim.cal is now a link to nextprime.cal.
    The lib/Makefile will take care of this link and install.

    The show command now takes singular forms.  For example, the
    command 'show builtin' does the same as 'show builtins'.  This
    allows show to match the historic singular names used in
    the help system.

    Synced 'show builtin' output with 'help builtin' output.

    Certain 64 bit processors such as the Alpha are now supported.

    Added -once to the READ command.  The command:

	read -once filename

    like the regular READ expect that it will ignore filename if
    is has been previously read.

    Improved the makefile.  One now can select the compiler type.  The
    make dependency lines are now simple foo.o: bar.h lines.  While
    this makes for a longer list, it is easier to maintain and will
    make future Makefile patches smaller.  Added special options for
    gcc version 1 & 2, and for cc on RS6000 systems.

    Calc compiles cleanly under the watchful eye of gcc version 2.4.5
    with the exception of warnings about 'aggregate has a partly
    bracketed initializer'.  (gcc v2 should allow you to disable
    this type of warning with using -Wall)

    Fixed a longjmp bug that clobbered a local variable in main().

    Fixed a number of cases where local variables or malloced storage was
    being used before being set.

    Fixed a number of fence post errors resulting in reads or writes
    just outside of malloced storage.

    A certain parallel processor optimizer would give up on
    code in cases where math_error() was called.  The obscure
    work-a-rounds involved initializing or making static, certain
    local variables.

    The cryrand.cal library has been improved.  Due to the way
    the initial quadratic residues are selected, the random numbers
    produced differ from previous versions.

    The printing of a leading '~' on rounded values is now a config
    option.  By default, tilde is still printed.  See help/config for
    details.

    The builtin function base() may be used to set the output mode or
    base.  Calling base(16) is a convenient shorthand for typing
    config("mode","hex").  See help/builtin.

    The printing of a leading tab is now a config option.  This does not
    alter the format of functions such as print or printf.  By default,
    a tab is printed.  See help/config for details.

    The value atan2(0,0) now returns 0 value in conformance with
    the 4.3BSD ANSI/IEEE 754-1985 math library.

    For all values of x, x^0 yields 1.  The major change here is
    that 0^0 yields 1 instead of an error.

    Fixed gcd() bug that caused gcd(2,3,1/2) to ignore the 1/2 arg.

    Fixed ltol() rounding so that exact results are returned, similar
    to the way sqrt() and hypot() round, when they exist.

    The file help/full is now being built.

    The man page is not installed by default.  One may install either
    the man page source or the cat (formatted man) page.  See the
    Makefile for details.

    Added a quit binding.  The file lib/bindings2 shows how this new
    binding may be used.

    One can now do a 'make check' to run the calc regression test
    within in the source tree.

    The regression test code is now more extensive.

    Updated the help/todo list.  A BUGS file was added.  Volunteers are
    welcome to send in patches!

Following is the change from calc version 2.9.1 to 2.9.2:

    Fixed floor() for values -1 < x < 0.

    Fixed ceil() for values -1 < x < 0.

    Fixed frac() for values < 0 so that int(x) + frac(x) == x.

    Fixed wild fetch bug in zdiv, zquo and zmod code.

    Fixed bug which caused regression test #719 to fail on some machines.

    Added more regression test code.

Following is the change from calc version 2.9.0 to 2.9.1:

    A major bug was fixed in subtracting two numbers when the first
    number was zero.  The problem caused wrong answers and core dumps.

Following is a list of visible changes to calc from version 1.27.0 to 2.9.0:

    Full prototypes have been provided for all C functions, and are used
    if calc is compiled with an ANSI compiler.

    Newly defined variables are now initialized to the value of zero instead
    of to the null value.  The elements of new objects are also initialized
    to the value of zero instead of null.

    The gcd, lcm, and ismult functions now work for fractional values.

    A major bug in the // division for fractions with a negative divisor
    was fixed.

    A major bug in the calculation of ln for small values was fixed.

    A major bug in the calculation of the ln and power functions for complex
    numbers was fixed.

    A major lack of precision for sin and tan for small values was fixed.

    A major lack of precision for complex square roots was fixed.

    The "static" keyword has been implemented for variables.  So permanent
    variables can be defined to have either file scope or function scope.

    Initialization of variables during their declaration are now allowed.
    This is most convenient for the initialization of static variables.

    The matrix definition statement can now be used within a declaration
    statement, to immediately define a variable as a matrix.

    Initializations of the elements of matrices are now allowed.  One-
    dimensional matrices may have implicit bounds when initialization is
    used.

    The obj definition statement can now be used within a declaration
    statement, to immediately define a variable as an object.

    Object definitions can be repeated as long as they are exactly the same
    as the previous definition.  This allows the rereading of files which
    happen to define objects.

    The integer, rational, and complex routines have been made into a
    'libcalc.a' library so that they can be used in other programs besides
    the calculator.  The "math.h" include file has been split into three
    include files: "zmath.h", "qmath.h", and "cmath.h".

Following is a list of visible changes to calc from version 1.26.4 to 1.27.0:

    Added an assoc function to return a new type of value called an
    association.  Such values are indexed by one or more arbitrary values.
    They are stored in a hash table for quick access.

    Added a hash() function which accepts one or more values and returns
    a quickly calculated small non-negative hash value for those values.

Following is a list of visible changes to calc from version 1.26.2 to 1.26.4:

    Misc fixes to Makefiles.

    Misc lint fixes.

    Misc portability fixes.

    Misc typo and working fixes to comments, help files and the man page.

Following is a list of visible changes to calc from version 1.24.7 to 1.26.2:

    There is a new emacs-like command line editing and edit history
    feature.  The old history mechanism has been removed.  The key
    bindings for the new editing commands are slightly configurable
    since they are read in from an initialization file.  This file is
    usually called /usr/lib/calc/bindings, but can be changed by the
    CALCBINDINGS environment variable.  All editing code is
    self-contained in the new files hist.c and hist.h, which can be
    easily extracted and used in other programs.

    Two new library files have been added: chrem.cal and cryrand.cal.
    The first of these solves the chinese remainder problem for a set
    of modulos and remainders.  The second of these implements several
    very good random number generators for large numbers.

    A small bug which allowed division by zero was fixed.

    A major bug in the mattrans function was fixed.

    A major bug in the acos function for negative arguments was fixed.

    A major bug in the strprintf function when objects were being printed
    was fixed.

    A small bug in the library file regress.cal was fixed.

*************
* libcalc
*************

	USING THE ARBITRARY PRECISION ROUTINES IN A C PROGRAM


Part of the calc release consists of an arbitrary precision math library.
This library is used by the calc program to perform its own calculations.
If you wish, you can ignore the calc program entirely and call the arbitrary
precision math routines from your own C programs.

The library is called libmath.a, and provides routines to handle arbitrary
precision arithmetic with integers, rational numbers, or complex numbers.
There are also many numeric functions such as factorial and gcd, along
with some transcendental functions such as sin and exp.

-------------
INCLUDE FILES
-------------

To use any of these routines in your own programs, you need to include the
appropriate include file.  These include files are:

	zmath.h		(for integer arithmetic)
	qmath.h		(for rational arithmetic)
	cmath.h		(for complex number arithmetic)

You never need to include more than one of the above files, even if you wish
to use more than one type of arithmetic, since qmath.h automatically includes
zmath.h, and cmath.h automatically includes qmath.h.

The prototypes for the available routines are listed in the above include
files.  Some of these routines are meant for internal use, and so aren't
convenient for outside use.  So you should read the source for a routine
to see if it really does what you think it does.  I won't guarantee that
obscure internal routines won't change or disappear in future releases!

When calc is installed, all of the include files needed to build
libcalc.a along with the library itself (and the lint library
llib-lcalc.ln, if made) are installed into /usr/local/lib/calc.

External programgs may want to compile with:
	
	-I/usr/local/lib/calc -L/usr/local/lib/calc -lcalc

--------------
ERROR HANDLING
--------------

You program MUST provide a function called math_error.  This is called by
the math routines on an error condition, such as malloc failures or a
division by zero.  The routine is called in the manner of printf, with a
format string and optional arguments.  (However, none of the low level math
routines currently uses formatting, so if you are lazy you can simply use
the first argument as a simple error string.)  For example, one of the
error calls you might expect to receive is:

	math_error("Division by zero");

Your program can handle errors in basically one of two ways.  Firstly, it
can simply print the error message and then exit.  Secondly, you can make
use of setjmp and longjmp in your program.  Use setjmp at some appropriate
level in your program, and use longjmp in the math_error routine to return
to that level and so recover from the error.  This is what the calc program
does.

---------------
OUTPUT ROUTINES
---------------

The output from the routines in the library normally goes to stdout.  You
can divert that output to either another FILE handle, or else to a string.
Read the routines in zio.c to see what is available.  Diversions can be
nested.

You use math_setfp to divert output to another FILE handle.  Calling
math_setfp with stdout restores output to stdout.

Use math_divertio to begin diverting output into a string.  Calling
math_getdivertedio will then return a string containing the output, and
clears the diversion.  The string is reallocated as necessary, but since
it is in memory, there are obviously limits on the amount of data that can
be diverted into it.  The string needs freeing when you are done with it.

Calling math_cleardiversions will clear all the diversions to strings, and
is useful on an error condition to restore output to a known state.  You
should also call math_setfp on errors if you had changed that.

If you wish to mix your own output with numeric output from the math routines,
then you can call math_chr, math_str, math_fill, math_fmt, or math_flush.
These routines output single characters, output null-terminated strings,
output strings with space filling, output formatted strings like printf, and
flush the output.  Output from these routines is diverted as described above.

You can change the default output mode by calling math_setmode, and you can
change the default number of digits printed by calling math_setdigits.  These
routines return the previous values.  The possible modes are described in
zmath.h.

--------------
USING INTEGERS
--------------

The arbitrary precision integer routines define a structure called a ZVALUE.
This is defined in zmath.h.  A ZVALUE contains a pointer to an array of
integers, the length of the array, and a sign flag.  The array is allocated
using malloc, so you need to free this array when you are done with a
ZVALUE.  To do this, you should call zfree with the ZVALUE as an argument
(or call freeh with the pointer as an argument) and never try to free the
array yourself using free.  The reason for this is that sometimes the pointer
points to one of two statically allocated arrays which should NOT be freed.

The ZVALUE structures are passed to routines by value, and are returned
through pointers.  For example, to multiply two small integers together,
you could do the following:

	ZVALUE	z1, z2, z3;

	itoz(3L, &z1);
	itoz(4L, &z2);
	zmul(z1, z2, &z3);

Use zcopy to copy one ZVALUE to another.  There is no sharing of arrays
between different ZVALUEs even if they have the same value, so you MUST
use this routine.  Simply assigning one value into another will cause
problems when one of the copies is freed.  However, the special ZVALUE
values _zero_ and _one_ CAN be assigned to variables directly, since their
values of 0 and 1 are so common that special checks are made for them.

For initial values besides 0 or 1, you need to call itoz to convert a long
value into a ZVALUE, as shown in the above example.  Or alternatively,
for larger numbers you can use the atoz routine to convert a string which
represents a number into a ZVALUE.  The string can be in decimal, octal,
hex, or binary according to the leading digits.

Always make sure you free a ZVALUE when you are done with it or when you
are about to overwrite an old ZVALUE with another value by passing its
address to a routine as a destination value, otherwise memory will be
lost.  The following shows an example of the correct way to free memory
over a long sequence of operations.

	ZVALUE z1, z2, z3;

	z1 = _one_;
	atoz("12345678987654321", &z2);
	zadd(z1, z2, &z3);
	zfree(z1);
	zfree(z2);
	zsquare(z3, &z1);
	zfree(z3);
	itoz(17L, &z2);
	zsub(z1, z2, &z3);
	zfree(z1);
	zfree(z2);
	zfree(z3);

There are some quick checks you can make on integers.  For example, whether
or not they are zero, negative, even, and so on.  These are all macros
defined in zmath.h, and should be used instead of checking the parts of the
ZVALUE yourself.  Examples of such checks are:

	ziseven(z)	(number is even)
	zisodd(z)	(number is odd)
	ziszero(z)	(number is zero)
	zisneg(z)	(number is negative)
	zispos(z)	(number is positive)
	zisunit(z)	(number is 1 or -1)
	zisone(z)	(number is 1)

There are two types of comparisons you can make on ZVALUEs.  This is whether
or not they are equal, or the ordering on size of the numbers.  The zcmp
function tests whether two ZVALUEs are equal, returning TRUE if they differ.
The zrel function tests the relative sizes of two ZVALUEs, returning -1 if
the first one is smaller, 0 if they are the same, and 1 if the first one
is larger.

---------------
USING FRACTIONS
---------------

The arbitrary precision fractional routines define a structure called NUMBER.
This is defined in qmath.h.  A NUMBER contains two ZVALUEs for the numerator
and denominator of a fraction, and a count of the number of uses there are
for this NUMBER.  The numerator and denominator are always in lowest terms,
and the sign of the number is contained in the numerator.  The denominator
is always positive.  If the NUMBER is an integer, the denominator has the
value 1.

Unlike ZVALUEs, NUMBERs are passed using pointers, and pointers to them are
returned by functions.  So the basic type for using fractions is not really
(NUMBER), but is (NUMBER *).  NUMBERs are allocated using the qalloc routine.
This returns a pointer to a number which has the value 1.  Because of the
special property of a ZVALUE of 1, the numerator and denominator of this
returned value can simply be overwritten with new ZVALUEs without needing
to free them first.  The following illustrates this:

	NUMBER *q;

	q = qalloc();
	itoz(55L, &q->num);

A better way to create NUMBERs with particular values is to use the itoq,
iitoq, or atoq functions.  Using itoq makes a long value into a NUMBER,
using iitoq makes a pair of longs into the numerator and denominator of a
NUMBER (reducing them first if needed), and atoq converts a string representing
a number into the corresponding NUMBER.  The atoq function accepts input in
integral, fractional, real, or exponential formats.  Examples of allocating
numbers are:

	NUMBER *q1, *q2, *q3;

	q1 = itoq(66L);
	q2 = iitoq(2L, 3L);
	q3 = atoq("456.78");

Also unlike ZVALUEs, NUMBERs are quickly copied.  This is because they contain
a link count, which is the number of pointers there are to the NUMBER.  The
qlink macro is used to copy a pointer to a NUMBER, and simply increments
the link count and returns the same pointer.  Since it is a macro, the
argument should not be a function call, but a real pointer variable.  The
qcopy routine will actually make a new copy of a NUMBER, with a new link
count of 1.  This is not usually needed.

NUMBERs are deleted using the qfree routine.  This decrements the link count
in the NUMBER, and if it reaches zero, then it will deallocate both of
the ZVALUEs contained within the NUMBER, and then puts the NUMBER structure
onto a free list for quick reuse.  The following is an example of allocating
NUMBERs, copying them, adding them, and finally deleting them again.

	NUMBER *q1, *q2, *q3;

	q1 = itoq(111L);
	q2 = qlink(q1);
	q3 = qadd(q1, q2);
	qfree(q1);
	qfree(q2);
	qfree(q3);

Because of the passing of pointers and the ability to copy numbers easily,
you might wish to use the rational number routines even for integral
calculations.  They might be slightly slower than the raw integral routines,
but are more convenient to program with.

The prototypes for the fractional routines are defined in qmath.h.
Many of the definitions for integer functions parallel the ones defined
in zmath.h.  But there are also functions used only for fractions.
Examples of these are qnum to return the numerator, qden to return the
denominator, qint to return the integer part of, qfrac to return the
fractional part of, and qinv to invert a fraction.

There are some transcendental functions in the library, such as sin and cos.
These cannot be evaluated exactly as fractions.  Therefore, they accept
another argument which tells how accurate you want the result.  This is an
"epsilon" value, and the returned value will be within that quantity of
the correct value.  This is usually an absolute difference, but for some
functions (such as exp), this is a relative difference.  For example, to
calculate sin(0.5) to 100 decimal places, you could do:

	NUMBER *q, *ans, *epsilon;

	q = atoq("0.5");
	epsilon = atoq("1e-100");
	ans = qsin(q, epsilon);

There are many convenience macros similar to the ones for ZVALUEs which can
give quick information about NUMBERs.  In addition, there are some new ones
applicable to fractions.  These are all defined in qmath.h.  Some of these
macros are:

	qiszero(q)	(number is zero)
	qisneg(q)	(number is negative)
	qispos(q)	(number is positive)
	qisint(q)	(number is an integer)
	qisfrac(q)	(number is fractional)
	qisunit(q)	(number is 1 or -1)
	qisone(q)	(number is 1)

The comparisons for NUMBERs are similar to the ones for ZVALUEs.  You use the
qcmp and qrel functions.

There are four predefined values for fractions.  You should qlink them when
you want to use them.  These are _qzero_, _qone_, _qnegone_, and _qonehalf_.
These have the values 0, 1, -1, and 1/2.  An example of using them is:

	NUMBER *q1, *q2;

	q1 = qlink(&_qonehalf_);
	q2 = qlink(&_qone_);

---------------------
USING COMPLEX NUMBERS
---------------------

The arbitrary precision complex arithmetic routines define a structure
called COMPLEX.  This is defined in cmath.h.  This contains two NUMBERs
for the real and imaginary parts of a complex number, and a count of the
number of links there are to this COMPLEX number.

The complex number routines work similarly to the fractional routines.
You can allocate a COMPLEX structure using comalloc (NOT calloc!).
You can construct a COMPLEX number with desired real and imaginary
fractional parts using qqtoc.  You can copy COMPLEX values using clink
which increments the link count.  And you free a COMPLEX value using cfree.
The following example illustrates this:

	NUMBER *q1, *q2;
	COMPLEX *c1, *c2, *c3;

	q1 = itoq(3L);
	q2 = itoq(4L);
	c1 = qqtoc(q1, q2);
	qfree(q1);
	qfree(q2);
	c2 = clink(c1);
	c3 = cmul(c1, c2);
	cfree(c1);
	cfree(c2);
	cfree(c3);

As a shortcut, when you want to manipulate a COMPLEX value by a real value,
you can use the caddq, csubq, cmulq, and cdivq routines.  These accept one
COMPLEX value and one NUMBER value, and produce a COMPLEX value.

There is no direct routine to convert a string value into a COMPLEX value.
But you can do this yourself by converting two strings into two NUMBERS,
and then using the qqtoc routine.

COMPLEX values are always returned from these routines.  To split out the
real and imaginary parts into normal NUMBERs, you can simply qlink the
two components, as shown in the following example:

	COMPLEX *c;
	NUMBER *rp, *ip;

	c = calloc();
	rp = qlink(c->real);
	ip = qlink(c->imag);

There are many macros for checking quick things about complex numbers,
similar to the ZVALUE and NUMBER macros.  In addition, there are some
only used for complex numbers.  Examples of macros are:

	cisreal(c)	(number is real)
	cisimag(c)	(number is pure imaginary)
	ciszero(c)	(number is zero)
	cisrunit(c)	(number is 1 or -1)
	cisiunit(c)	(number is i or -i)
	cisunit(c)	(number is 1, -1, i, or -i)

There is only one comparison you can make for COMPLEX values, and that is
for equality.  The ccmp function returns TRUE if two complex numbers differ.

There are three predefined values for complex numbers.  You should clink
them when you want to use them.  They are _czero_, _cone_, and _conei_.
These have the values 0, 1, and i.

*************
* stdlib
*************

# Copyright (c) 1994 David I. Bell and Landon Curt Noll
# Permission is granted to use, distribute, or modify this source,
# provided that this copyright notice remains intact.

The following calc library files are provided because they serve as 
examples of how use the calc language, and because the authors thought 
them to be useful!

If you write something that you think is useful, please send it to:

    dbell@canb.auug.org.au
    chongo@toad.com                 {uunet,pyramid,sun}!hoptoad!chongo

By convention, a lib file only defines and/or initializes functions,
objects and variables.  (The regression test is an exception.)  Also by
convention, the a usage message regarding each important object and
function is printed at the time of the read.

If a lib file needs to load another lib file, it should use the -once
version of read:

    /* pull in needed library files */
    read -once "cryrand"
    read -once "curds"

This will cause the needed library files to be read once.  If these
files have already been read, the read -once will act as a noop.

By convention, the global variable  lib_debug  is used to control
the verbosity of debug information printed by lib files.  By default,
the lib_debug has a value of 0.  If lib_debug < 0, then no debug
messages are printed.  If lib_debug >= 0, then only usage message 
regarding each important object are printed at the time of the read.
If lib_debug == 0, then only such usage messages are printed; no
other debug information is printed.

To conform to the above convention, your lib files should end with
lines of the form:

	global lib_debug;
	if (lib_debug >= 0) {
	    print "funcA(side_a, side_b, side_c) defined";
	    print "funcB(size, mass) defined";
	}


=-=


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.


bigprime.cal

    bigprime(a, m, p) 

    A prime test, base a, on p*2^x+1 for even x>m.


chrem.cal

    chrem(r1,m1 [,r2,m2, ...])
    chrem(rlist, mlist)

    Chinese remainder theorem/problem solver.


cryrand.cal

    shufrand()
    sshufrand(seed)
    rand([a, [b]])
    srand(seed)
    cryrand([a, [b]])
    scryrand([seed, [len1, len2]])
    random([a, [b]])
    srandom(seed)
    obj cryobj
    randstate([cryobj | 0])
    nxtprime(n, [val, modulus])

    Cryptographically strong pseudo-random number generator library.
    

deg.cal		

    dms(deg, min, sec)
    dms_add(a, b)
    dms_neg(a)
    dms_sub(a, b)
    dms_mul(a, b)
    dms_print(a)

    Calculate in degrees, minutes, and seconds.


ellip.cal	

    factor(iN, ia, B, force)

    Attempt to factor using the elliptic functions: y^2 = x^3 + a*x + b.


lucas.cal

    lucas(h, n)

    Perform a primality test of h*2^n-1, with 1<=h<2*n.


lucas_chk.cal

    lucas_chk(high_n)

    Test all primes of the form h*2^n-1, with 1<=h<200 and n <= high_n.
    Requires lucas.cal to be loaded.  The highest useful high_n is 1000.


lucas_tbl.cal

    Lucasian criteria for primality tables.


mersenne.cal

    mersenne(p)

    Perform a primality test of 2^p-1, for prime p>1.


mod.cal	

    mod(a)
    mod_print(a)
    mod_one()
    mod_cmp(a, b)
    mod_rel(a, b)
    mod_add(a, b)
    mod_sub(a, b)
    mod_neg(a)
    mod_mul(a, b)
    mod_square(a)
    mod_inc(a)
    mod_dec(a)
    mod_inv(a)
    mod_div(a, b)
    mod_pow(a, b)

    Routines to handle numbers modulo a specified number.


nextprime.cal

    nextprime(n, tries)

    Function to find the next prime (probably).


pell.cal

    pellx(D)
    pell(D)

    Solve Pell's equation; Returns the solution X to: X^2 - D * Y^2 = 1.
    Type the solution to pells equation for a particular D.


pi.cal

    qpi(epsilon)

    Calculate pi within the specified epsilon using the quartic convergence
    iteration.


pollard.cal

    factor(N, N, ai, af)

    Factor using Pollard's p-1 method.


poly.cal	

    Calculate with polynomials of one variable.  There are many functions.
    Read the documentation in the library file.


psqrt.cal	

    psqrt(u, p)

    Calculate square roots modulo a prime


quat.cal

    quat(a, b, c, d)
    quat_print(a)
    quat_norm(a)
    quat_abs(a, e)
    quat_conj(a)
    quat_add(a, b)
    quat_sub(a, b)
    quat_inc(a)
    quat_dec(a)
    quat_neg(a)
    quat_mul(a, b)
    quat_div(a, b)
    quat_inv(a)
    quat_scale(a, b)
    quat_shift(a, b)

    Calculate using quaternions of the form: a + bi + cj + dk.  In these
    functions, quaternians are manipulated in the form: s + v, where
    s is a scalar and v is a vector of size 3.


randmprime.cal

    randmprime(bits, seed [,dbg])

    Find a prime of the form h*2^n-1 >= 2^bits for some given x.  The initial
    search points for 'h' and 'n' are selected by a cryptographic pseudo-random
    number generator.  The optional argument, dbg, if set to 1, 2 or 3
    turn on various debugging print statements.


regress.cal	

    Test the correct execution of the calculator by reading this library file.
    Errors are reported with '****' mssages, or worse.  :-)


solve.cal	

    solve(low, high, epsilon)

    Solve the equation f(x) = 0 to within the desired error value for x.
    The function 'f' must be defined outside of this routine, and the low
    and high values are guesses which must produce values with opposite signs.


sumsq.cal	

    ss(p)

    Determine the unique two positive integers whose squares sum to the
    specified prime.  This is always possible for all primes of the form
    4N+1, and always impossible for primes of the form 4N-1.


surd.cal	

    surd(a, b)
    surd_print(a)
    surd_conj(a)
    surd_norm(a)
    surd_value(a, xepsilon)
    surd_add(a, b)
    surd_sub(a, b)
    surd_inc(a)
    surd_dec(a)
    surd_neg(a)
    surd_mul(a, b)
    surd_square(a)
    surd_scale(a, b)
    surd_shift(a, b)
    surd_div(a, b)
    surd_inv(a)
    surd_sgn(a)
    surd_cmp(a, b)
    surd_rel(a, b)

    Calculate using quadratic surds of the form: a + b * sqrt(D).


test1000.cal

    This script is used by regress.cal to test the read and use keywords.


unitfrac.cal

    unitfrac(x)

    Represent a fraction as sum of distinct unit fractions.


varargs.cal

    sc(a, b, ...)

    Example program to use 'varargs'.  Program to sum the cubes of all 
    the specified numbers.

*************
* bugs
*************

We welcome comments, suggestions and most importantly, fixes in the
form of a patch.  Send such items to:

    dbell@canb.auug.org.au
    chongo@toad.com		    {uunet,pyramid,sun}!hoptoad!chongo

The following are the known bugs and mis-features in 2.9.3.  

    * Saber C warns about several problems related to accessing memory
      that has not been previously set.  Purify, on the other hand,
      does not issue such warnings.  These problems need to be looked
      into and if they are real, they need to be fixed.

      One may not need Saber C to work on this problem.  The warning
      spots have been marked as comments in the source.  To find these
      warnings, grep for the XXX symbol in the source.

    * Purify reports that calc leaks memory.  Plug these leaks or
      determine that such leaks are non-issues.
    
    * Calc does not support negative mods.

    * The output of list(2,3,4) is indented differently from list().

*************
* todo
*************

Needed enhancements

	Send calc comments, suggestions, bug fixes, enhancements and
	interesting calc scripts that you would like you see included in
	future distributions to:

		dbell@canb.auug.org.au
		chongo@toad.com

	The following items are in the calc wish list.  Programs like this
	can be extended and improved forever.

	*  Implement an autoload feature.  Associate a calc library filename
	   with a function or global variable.  On the first reference of
	   such item, perform an automatic load of that file.

	*  Use faster multiply and divide algorithms for large numbers.

	*  Add error handling statements, so that QUITs, errors from the 
	   'eval' function, division by zeroes, and so on can be caught.
	   This should be done using syntax similar to:

		    ONERROR statement DO statement;

	   Something like signal isn't versatile enough.

	*  Add a debugging capability so that functions can be single stepped,
	   breakpoints inserted, variables displayed, and so on.

	*  Figure out how to write all variables out to a file, including
	   deeply nested arrays, lists, and objects.

	*  Implement pointers.

	*  Eliminate the need for the define keyword by doing smarter parsing.

	*  Allow results of a command (or all commands) to be re-directed to a 
	   file or piped into a command.

	*  Add some kind of #include and #define facility.  Perhaps use
	   the C pre-processor itself?

	*  Allow one to undefine anything.  Allow one to test if anything
	   is defined.

	*  Support a more general input and output base mode other than
	   just dec, hex or octal.

	*  Implement a form of symbolic algebra.  Work on this has already
	   begun.  This will use backquotes to define expressions, and new
	   functions will be able to act on expressions.  For example:

	   	x = `hello * strlen(mom)`;
		x = sub(x, `hello`, `hello + 1`);
		x = sub(x, `hello`, 10, `mom`, "curds");
		eval(x);

	   prints 55.
	
	*  Place the results of previous commands into a parallel history list.
	   Add a binding that returns the saved result of the command so
	   that one does not need to re-execute a previous command simply
	   to obtain its value.

	   If you have a command that takes a very long time to execute,
	   it would be nice if you could get at its result without having
	   to spend the time to reexecute it.

	*  Add a binding to delete a value from the history list.

	   One may need to remove a large value from the history list if
	   it is very large.  Deleting the value would replace the history
	   entry with a null value.

	*  Add a binding to delete a command from the history list.

	   Since you can delete values, you might as well be able to
	   delete commands.

	*  All one to alter the size of the history list thru config().

	   In some cases, 256 values is too small, in others it is too large.

	*  Add a builtin that returns a value from the history list.
	   As an example:

		histval(-10)
	
	   returns the 10th value on the history value list, if such 
	   a value is in the history list (null otherwise).  And:

		histval(23)
	
	   return the value of the 23rd command given to calc, if
	   such a value is in the history list (null otherwise).

	   It would be very helpful to use the history values in
	   subsequent equations.

	*  Add a builtin that returns command as a string from the
	   history list.  As an example:

		history(-10)
	
	   returns a string containing the 10th command on the
	   history list, if a such a value is in the history list 
	   (empty string otherwise).  And:

		history(23)
	
	   return the string containing the 23rd command given to calc, if
	   such a value is in the history list (empty string otherwise).

	   One could use the eval() function to re-evaluate the command.

	*  Allow one to optionally restore the command number to calc 
	   prompts.  When going back in the history list, indicate the 
	   command number that is being examined.

	   The command number was a useful item.  When one is scanning the
	   history list, knowing where you are is hard without it.  It can
	   get confusing when the history list wraps or when you use
	   search bindings.  Command numbers would be useful in
	   conjunction with positive args for the history() and histval()
	   functions as suggested above.

	*  Add a builtin that returns the current command number.
	   For example:

		cmdnum()

	   returns the current command number.

	   This would allow one to tag a value in the history list.  One
	   could save the result of cmdnum() in a variable and later use
	   it as an arg to the histval() or history() functions.

	*  Add a builtin to determine if an object as been defined.
	   For example:

		isobjdef("surd")

	   would return true if one had previously defined the
	   surd object.  I.e., if "obj surd {...};" had been
	   executed.

	   One cannot redefine an object.  If a script defines an object,
	   one cannot reload it without getting lots of already defined
	   errors.  If two scripts needed the same object, both could
	   define it and use isobjdef() to avoid redefinition problems.

	*  Add a builtin to determine if a function as been defined.
	   For example:

		isfunct("foo")

	   would return true if foo has been defined as a function.

	*  Permit one to destroy an object.

	   What if one does want to redefine an object?  Consider the case
	   where one it debugging a script and wants to reload it.  If
	   that script defines an object you are doomed.  Perhaps
	   destroying a object would undefine all of its related functions
	   and values?

	*  One some machines (such as the 486), floating point can be faster 
	   than integer arithmetic.  Often such floating point would allow
	   for a larger base than 2^16, allowing calc to run even faster.
	   Allow calc to take advantage of such hardware.
	
	*  Add NAN (Not A Number) to calc.  Where is it reasonable, change 
	   calc to process these values in way similar to that of the IEEE 
	   floating point.
	
	*  Add a factoring builtin functions.  Provide functions that perform 
	   multiple polynomial quadratic sieves, elliptic curve, difference 
	   of two squares, N-1 factoring as so on.  Provide a easy general 
	   factoring builtin (say factor(foo)) that would attempt to apply
	   whatever process was needed based on the value.

	   Factoring builtins would return a matrix of factors.

	   It would be handy to configure, via config(), the maximum time
	   that one should try to factor a number.  By default the time
	   should be infinite.  If one set the time limit to a finite
	   value and the time limit was exceeded, the factoring builtin
	   would return whatever if had found thus far, even if no new 
	   factors had been found.

	   Another factoring configuration interface, via config(), that
	   is needed would be to direct the factoring builtins to return
	   as soon as a factor was found.

	*  Allow one to config calc break up long output lines.

	   The command:  calc '2^100000'  will produce one very long
	   line.  Many times this is reasonable.  Long output lines
	   are a problem for some utilities.  It would be nice if one
	   could configure, via config(), calc to fold long lines.

	   By default, calc should continue to produce long lines.

	   One option to config should be to specify the length to
	   fold output.  Another option should be to append a trailing
	   \ on folded lines (as some symbolic packages use).

	*  Add scanf() and fscanf() functions.

	   The scanf function should be able to handle both long lines
	   and split lines with trailing \'s.  It should also be able
	   to ignore the leading ~.

	*  Add the ability to read and write a value in some binary form.

	   Clearly this is easy for non-neg integers.  The question of
	   everything else is worth pondering.
	
	*  Allow one to use the READ and WRITE commands inside a function.

*************
* credit
*************

Credits

	Written by David I. Bell.

	Thanks for suggestions and encouragement from Peter Miller,
	Neil Justusson, and Landon Noll.

	Thanks to Stephen Rothwell for writing the original version of
	hist.c which is used to do the command line editing.

	Thanks to Ernest W. Bowen for supplying some improvements in
	accuracy and generality for some numeric functions.  Much of
	this was in terms of actual code which I gratefully accepted.

	Portions of this program are derived from an earlier set of
	public domain arbitrarily precision routines which was posted
	to the net around 1984.  By now, there is almost no recognizable 
	code left from that original source.

	Most of this source and binary is:

		Copyright (c) 1993 David I. Bell

	A few files are a joint copyright between David I. Bell and Landon Noll.

	Permission is granted to use, distribute, or modify this source,
	provided that this copyright notice remains intact.

	Send calc comments, suggestions, bug fixes, enhancements and
	interesting calc scripts that you would like you see included in
	future distributions to:

		dbell@canb.auug.org.au
		chongo@toad.com

	Enjoy!
