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

What is calc?

    Calc 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

    Calc as the usual collection of arithmetic operators +, -, /, *
    as well as ^ (exponentiation), % (modulus) and // (integer divide).
    For example:

	    3 * 19^43 - 1

     will produce:

	    29075426613099201338473141505176993450849249622191102976

    Notice that calc values can be very large.  For example:

    	    2^23209-1

    will print:

	   402874115778988778181873329071 ... many digits ... 3779264511

    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 modified by typing:

	    . % (2^127-1)

    and the calculator will print:

	    47385033654019111249345128555354223304

    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:

	    curds = 15
	    whey = 7 + 2*curds

    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(whey)

    and the calculator prints:

    	    13763753091226345046315979581580902400000000

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

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

    will print:

    	    17+6i
	    -55.50474777265624667147+193.9265235748927986537i

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

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

    prints:

    	0.8414709848078965066525023216302989996225630607983710656727517099919104

    Calc can output values in terms of fractions, octal or hexadecimal.
    For example:

    	    config("mode", "fraction"),
	    (17/19)^23
	    base(16),
	    (19/17)^29

     will print:

     	    19967568900859523802559065713/257829627945307727248226067259
	    0x9201e65bdbb801eaf403f657efcf863/0x5cd2e2a01291ffd73bee6aa7dcf7d1

    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:

	    help builtin

    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.

	    define f2(n)
	    {
		    local       ans;

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

    Thus the input:

	    f2(79)

    will produce;

	    1009847364737869270905302433221592504062302663202724609375

    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

    Thus the input:

	    sc(31, 61)

    will produce;

	    256772

    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.

    For more information about the calc language and features, try:

	    help overview

    In particular, check out the other help functions listed in the
    overview help file.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.3 $
## @(#) $Id: intro,v 29.3 2000/06/07 15:26:20 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/intro,v $
##
## Under source code control:	1991/07/21 04:37:21
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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.

    Calc has a help command that will produce information about
    every builtin function, command as well as a number of other
    aspects of calc usage.  Try the command:

	    help help

    for and overview of the help system.  The command:

	    help builtin

    provides information on built-in mathematical functions, whereas:

	    help asinh

    will provides information a specific function.  The following
    help files:

	    help command
	    help define
	    help operator
	    help statement
	    help variable

    provide a good overview of the calc language.  If you are familiar
    with C, you should also try:

	    help unexpected

    It contains information about differences between C and calc
    that may surprize you.

    To learn about calc standard resource files, try:

	    help resource

    To learn how to invoke the calc command and about calc -flags, try:

	    help usage

    To learn about calc shell scripts, try:

	    help script

    A full and extensive overview of calc may be obtained by:

	    help full

    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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: overview,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/overview,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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
    custom		information about the custom builtin interface
    define		how to define functions
    environment		how environment variables effect calc
    errorcodes		calc generated error codes
    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
    types		builtin data types
    unexpected		unexpected syntax/usage surprises for C programmers
    usage		how to invoke the calc command
    variable		variables and variable declarations

    bindings		input & history character bindings
    custom_cal		information about custom calc resource files
    libcalc		using the arbitrary precision routines in a C program
    new_custom		information about how to add new custom functions
    resource		standard calc resource files
    script		using calc shell scripts
    cscript		info on the calc shell scripts supplied with calc

    archive		where to get the latest versions of calc
    bugs		known bugs and mis-features
    changes		recent changes to calc
    contrib		how to contribute scripts, code or custom functions
    todo		list of priority action items for calc
    wishlist		wish list of future enhancements of calc

    credit		who wrote calc and who helped
    copyright		calc copyright and the GNU LGPL
    copying		details on the Calc GNU Lesser General Public License
    copying-lgpl	calc GNU Lesser General Public License text

    full		all of the above (in the above order)

You can also ask for help on a particular function name.  For example,

    help asinh
    help round

or on a particular symbol such as:

    help =

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.

If the -m mode disallows opening files for reading or execution of programs,
then the help facility will be disabled.  See:

    help usage

for details of the -m mode.

The help command is able to display installed help files for custom builtin
functions.  However, if the custom name is the same as a standard help
file, the standard help file will be displayed instead.	 The custom help
builtin should be used to directly access the custom help file.

For example, the custom help builtin has the same name as the standard
help file.  That is:

    help help

will print this file only.  However the custom help builtin will print
only the custom builtin help file:

    custom("help", "help");

will by-pass a standard help file and look for the custom version directly.

As a hack, the following:

     help custhelp/anything

as the same effect as:

    custom("help", "anything");

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.3 $
## @(#) $Id: help,v 29.3 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/help,v $
##
## Under source code control:	1991/07/21 04:37:20
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* assoc
*************

NAME
    assoc - create a new association array

SYNOPSIS
    assoc()

TYPES
    return	association

DESCRIPTION
    This function returns an empty association array.

    After A = assoc(), elements can be added to the association by
    assignments of the forms

	A[a_1] = v_1
	A[a_1, a_2] = v_2
	A[a_1, a_2, a_3] = v_3
	A[a_1, a_2, a_3, a_4] = v_4

    There are no restrictions on the values of the "indices" a_i or
    the "values" v_i.

    After the above assignments, so long as no new values have been
    assigned to A[a_i], etc., the expressions A[a_1], A[a_1, a_2], etc.
    will return the values v_1, v_2, ...

    Until A[a_1], A[a_1, a_2], ... are defined as described above, these
    expressions return the null value.

    Thus associations act like matrices except that different elements
    may have different numbers (between 1 and 4 inclusive) of indices,
    and these indices need not be integers in specified ranges.

    Assignment 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 is undefined.

    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.

EXAMPLE
    > A = assoc(); print A
     assoc (0 elements):

    > A["zero"] = 0; A["one"] = 1; A["two"] = 2; A["three"] = 3;
    > A["smallest", "prime"] = 2;
    > print A
    assoc (5 elements);
    ["two"] = 2
    ["three"] = 3
    ["one"] = 1
    ["zero"] = 0
    ["smallest","prime"] = 2

LIMITS
    none

LINK LIBRARY
    none

SEE ALSO
    isassoc, rsearch, search, size

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.3 $
## @(#) $Id: assoc,v 29.3 2002/07/10 11:47:04 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/assoc,v $
##
## Under source code control:	1994/09/25 20:22:31
## File existed as early as:	1994
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: builtin.top,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/builtin.top,v $
##
## Under source code control:	1995/07/10 01:17:53
## File existed as early as:	1995
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

	Name	Args	Description

	abs       1-2   absolute value within accuracy b
	access    1-2   determine accessibility of file a for mode b
	acos      1-2   arccosine of a within accuracy b
	acosh     1-2   inverse hyperbolic cosine of a within accuracy b
	acot      1-2   arccotangent of a within accuracy b
	acoth     1-2   inverse hyperbolic cotangent of a within accuracy b
	acsc      1-2   arccosecant of a within accuracy b
	acsch     1-2   inverse csch of a within accuracy b
	agd       1-2   inverse gudermannian function
	append    1+    append values to end of list
	appr      1-3   approximate a by multiple of b using rounding c
	arg       1-2   argument (the angle) of complex number
	argv      0-1   calc argc or argv string
	asec      1-2   arcsecant of a within accuracy b
	asech     1-2   inverse hyperbolic secant of a within accuracy b
	asin      1-2   arcsine of a within accuracy b
	asinh     1-2   inverse hyperbolic sine 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   inverse hyperbolic tangent of a within accuracy b
	avg       0+    arithmetic mean of values
	base      0-1   set default output base
	base2     0-1   set default secondary output base
	bernoulli 1     Bernoulli number for index a
	bit       2     whether bit b in value a is set
	blk       0-3   block with or without name, octet number, chunksize
	blkcpy    2-5   copy value to/from a block: blkcpy(d,s,len,di,si)
	blkfree   1     free all storage from a named block
	blocks    0-1   named block with specified index, or null value
	bround    1-3   round value a to b number of binary places
	btrunc    1-2   truncate a to b number of binary places
	calclevel 0     current calculation level
	calc_tty  0     set tty for interactivity
	catalan   1     catalan number for index a
	ceil      1     smallest integer greater than or equal to number
	cfappr    1-3   approximate a within accuracy b using
				 continued fractions
	cfsim     1-2   simplify number using continued fractions
	char      1     character corresponding to integer value
	cmdbuf    0     command buffer
	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
	copy      2-5   copy value to/from a block: copy(s,d,len,si,di)
	cos       1-2   cosine of value a within accuracy b
	cosh      1-2   hyperbolic cosine of a within accuracy b
	cot       1-2   cotangent of a within accuracy b
	coth      1-2   hyperbolic cotangent of a within accuracy b
	count     2     count listr/matrix elements satisfying some condition
	cp        2     cross product of two vectors
	csc       1-2   cosecant of a within accuracy b
	csch      1-2   hyperbolic cosecant of a within accuracy b
	ctime     0     date and time as string
	custom    0+    custom builtin function interface
	delete    2     delete element from list a at position b
	den       1     denominator of fraction
	det       1     determinant of matrix
	digit     2-3   digit at specified decimal place of number
	digits    1-2   number of digits in base b representation of a
	display   0-1   number of decimal digits for displaying numbers
	dp        2     dot product of two vectors
	epsilon   0-1   set or read allowed error for real calculations
	errcount  0-1   set or read error count
	errmax    0-1   set or read maximum for error count
	errno     0-1   set or read calc_errno
	error     0-1   generate error value
	euler     1     Euler number
	eval      1     evaluate expression from string to value
	exp       1-2   exponential of value a within accuracy b
	factor    1-3   lowest prime factor < b of a, return c if error
	fcnt      2     count of times one number divides another
	fib       1     Fibonacci number F(n)
	forall    2     do function for all elements of list or matrix
	frem      2     number with all occurrences of factor removed
	fact      1     factorial
	fclose    0+    close file
	feof      1     whether EOF reached for file
	ferror    1     whether error occurred for file
	fflush    0+    flush output to file(s)
	fgetc     1     read next char from file
	fgetfield 1     read next white-space delimited field from file
	fgetline  1     read next line from file, newline removed
	fgets     1     read next line from file, newline is kept
	fgetstr   1     read next null-terminated string from file, null character is kept
	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
	fputc     2     write a character to a file
	fputs     2+    write one or more strings to a file
	fputstr   2+    write one or more null-terminated strings to a file
	free      0+    free listed or all global variables
	freebernoulli 0     free stored Bernoulli numbers
	freeeuler 0     free stored Euler numbers
	freeglobals 0     free all global and visible static variables
	freeredc  0     free redc data cache
	freestatics 0     free all unscoped static variables
	freopen   2-3   reopen a file stream to a named file
	fscan     2+    scan a file for assignments to one or more variables
	fscanf    2+    formatted scan of a file for assignment to one or more variables
	fseek     2-3   seek to position b (offset from c) in file a
	fsize     1     return the size of the file
	ftell     1     return the file position
	frac      1     fractional part of value
	gcd       1+    greatest common divisor
	gcdrem    2     a divided repeatedly by gcd with b
	gd        1-2   gudermannian function
	getenv    1     value of environment variable (or NULL)
	hash      1+    return non-negative hash value for one or
			    more values
	head      2     return list of specified number at head of a list
	highbit   1     high bit number in base 2 representation
	hmean     0+    harmonic mean of values
	hnrmod    4     v mod h*2^n+r, h>0, n>0, r = -1, 0 or 1
	hypot     2-3   hypotenuse of right triangle within accuracy c
	ilog      2     integral log of a to integral base b
	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
	indices   2     indices of a specified assoc or mat value
	inputlevel 0     current input depth
	insert    2+    insert values 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
	isatty    1     whether a file is a tty
	isblk     1     whether a value is a block
	isconfig  1     whether a value is a config state
	isdefined 1     whether a string names a function
	iserror   1     where a value is an error
	iseven    1     whether a value is an even integer
	isfile    1     whether a value is a file
	ishash    1     whether a value is a hash state
	isident   1     returns 1 if identity matrix
	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
	isobjtype 1     whether a string names an object type
	isodd     1     whether a value is an odd integer
	isoctet   1     whether a value is an octet
	isprime   1-2   whether a is a small prime, return b if error
	isptr     1     whether a value is a pointer
	isqrt     1     integer part of square root
	isrand    1     whether a value is a additive 55 state
	israndom  1     whether a value is a Blum state
	isreal    1     whether a value is a real number
	isrel     2     whether two numbers are relatively prime
	isstr     1     whether a value is a string
	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
	join      1+    join one or more lists into one list
	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
	links     1     links to number or string value
	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))
	makelist  1     create a list with a null elements
	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
	matsum    1     sum the numeric values in a matrix
	mattrace  1     return the trace of a square matrix
	mattrans  1     transpose of matrix
	max       0+    maximum value
	md5       0+    MD5 Hash Algorithm
	memsize   1     number of octets used by the value, including overhead
	meq       3     whether a and b are equal modulo c
	min       0+    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
	mod       2-3   residue of a modulo b, rounding type c
	modify    2     modify elements of a list or matrix
	name      1     name assigned to block or file
	near      2-3   sign of (abs(a-b) - c)
	newerror  0-1   create new error type with message a
	nextcand  1-5   smallest value == d mod e > a, ptest(a,b,c) true
	nextprime 1-2   return next small prime, return b if err
	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)!
	prevcand  1-5   largest value == d mod e < a, ptest(a,b,c) true
	prevprime 1-2   return previous small prime, return b if err
	pfact     1     product of primes up till number
	pi        0-1   value of pi accurate to within epsilon
	pix       1-2   number of primes <= a < 2^32, return b if error
	places    1-2   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      1+    evaluates a polynomial given its coefficients or coefficient-list
	pop       1     pop value from front of list
	popcnt    1-2   number of bits in a that match b (or 1)
	power     2-3   value a raised to the power b within accuracy c
	protect   1-2   read or set protection level for variable
	ptest     1-3   probabilistic primality test
	printf    1+    print formatted output to stdout
	prompt    1     prompt for input line using value a
	push      1+    push values onto front of list
	putenv    1-2   define an environment variable
	quo       2-3   integer quotient of a by b, rounding type c
	quomod    4     set c and d to quotient and remainder of a
			    divided by b
	rand      0-2   additive 55 random number [0,2^64), [0,a), or [a,b)
	randbit   0-1   additive 55 random number [0,2^a)
	random    0-2   Blum-Blum-Shub random number [0,2^64), [0,a), or [a,b)
	randombit 0-1   Blum-Blum-Sub random number [0,2^a)
	randperm  1     random permutation of a list or matrix
	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
	reverse   1     reverse a copy of a matrix or list
	rewind    0+    rewind file(s)
	rm        1+    remove file(s), -f turns off no-such-file errors
	root      2-3   value a taken to the b'th root within accuracy c
	round     1-3   round value a to b number of decimal places
	rsearch   2-4   reverse search matrix or list for value b
			    starting at index c
	runtime   0     user mode cpu time in seconds
	saveval   1     set flag for saving values
	scale     2     scale value up or down by a power of two
	scan      1+    scan standard input for assignment to one or more variables
	scanf     2+    formatted scan of standard input for assignment to variables
	search    2-4   search matrix or list for value b starting
			    at index c
	sec       1-2   sec of a within accuracy b
	sech      1-2   hyperbolic secant of a within accuracy b
	seed      0     return a 64 bit seed for a psuedo-random generator
	segment   2-3   specified segment of specified list
	select    2     form sublist of selected elements from list
	setbit    2-3   set specified bit in string
	sgn       1     sign of value (-1, 0, 1)
	sha       0+    old Secure Hash Algorithm (SHS FIPS Pub 180)
	sha1      0+    Secure Hash Algorithm (SHS-1 FIPS Pub 180-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
	sizeof    1     number of octets used to hold the value
	sleep     0-1   suspend operation for a seconds
	sort      1     sort a copy of a matrix or list
	sqrt      1-3   square root of value a within accuracy b
	srand     0-1   seed the rand() function
	srandom   0-4   seed the random() function
	ssq       1+    sum of squares of values
	stoponerror 0-1   assign value to stoponerror flag
	str       1     simple value converted to string
	strcat    1+    concatenate strings together
	strcmp    2     compare two null-terminated strings
	strcpy    2     copy null-terminated string to string
	strerror  0-1   string describing error type
	strlen    1     length of string
	strncmp   3     compare strings a, b to c characters
	strncpy   3     copy up to c characters from string to string
	strpos    2     index of first occurrence of b in a
	strprintf 1+    return formatted output as a string
	strscan   2+    scan a string for assignments to one or more variables
	strscanf  2+    formatted scan of string for assignments to variables
	substr    3     substring of a from position b for c chars
	sum       0+    sum of list or object sums and/or other terms
	swap      2     swap values of variables a and b (can be dangerous)
	system    1     call Unix command
	tail      2     retain list of specified number at tail of list
	tan       1-2   tangent of a within accuracy b
	tanh      1-2   hyperbolic tangent of a within accuracy b
	test      1     test that value is nonzero
	time      0     number of seconds since 00:00:00 1 Jan 1970 UTC
	trunc     1-2   truncate a to b number of decimal places
	ungetc    2     unget char read from file
	version   0     calc version string
	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 bit 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
	bit(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 builtin is a primality testing function.  The
	1st argument is the suspected prime to be tested.  The
	absolute value of the 2nd argument is an iteration count.

	If ptest is called with only 2 args, the 3rd argument is
	assumed to be 0.  If ptest is called with only 1 arg, the
	2nd argument is assumed to be 1.  Thus, the following
	calls are equivalent:

		ptest(a)
		ptest(a,1)
		ptest(a,1,0)

	Normally ptest performs a some checks to determine if the
	value is divisable by some trivial prime.  If the 2nd
	argument is < 0, then the trivial check is omitted.

	For example, ptest(a,10) performs the same work as:

		ptest(a,-3)	(7 tests without trivial check)
		ptest(a,-7,3)	(3 more tests without the trivial check)

	The ptest 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 first 3 args of nextcand and prevcand functions are the same
	arguments as ptest.  But unlike ptest, nextcand and prevcand return
	the next and previous values for which ptest is true.

	For example, nextcand(2^1000) returns 2^1000+297 because
	2^1000+297 is the smallest value x > 2^1000 for which
	ptest(x,1) is true.  And for example, prevcand(2^31-1,10,5)
	returns 2147483629 (2^31-19) because 2^31-19 is the largest
	value y < 2^31-1 for which ptest(y,10,5) is true.

	The nextcand and prevcand functions also have a 5 argument form:

		nextcand(num, count, skip, modval, modulus)
		prevcand(num, count, skip, modval, modulus)

	return the smallest (or largest) value ans > num (or < num) that
	is also == modval % modulus for which ptest(ans,count,skip) is true.

	The builtins nextprime(x) and prevprime(x) return the
	next and previous primes with respect to x respectively.
	As of this release, x must be < 2^32.  With one argument, they
	will return an error if x is out of range.  With two arguments,
	they will not generate an error but instead will return y.

	The builtin function pix(x) returns the number of primes <= x.
	As of this release, x must be < 2^32.  With one argument, pix(x)
	will return an error if x is out of range.  With two arguments,
	pix(x,y) will not generate an error but instead will return y.

	The builtin function factor may be used to search for the
	smallest factor of a given number.  The call factor(x,y)
	will attempt to find the smallest factor of x < min(x,y).
	As of this release, y must be < 2^32.  If y is omitted, y
	is assumed to be 2^32-1.

	If x < 0, factor(x,y) will return -1.  If no factor <
	min(x,y) is found, factor(x,y) will return 1.  In all other
	cases, factor(x,y) will return the smallest prime factor
	of x.  Note except for the case when abs(x) == 1, factor(x,y)
	will not return x.

	If factor is called with y that is too large, or if x or y
	is not an integer, calc will report an error.  If a 3rd argument
	is given, factor will return that value instead.  For example,
	factor(1/2,b,c) will return c instead of issuing an error.

	The builtin lfactor(x,y) searches a number of primes instead
	of below a limit.  As of this release, y must be <= 203280221
	(y <= pix(2^32-1)).  In all other cases, lfactor is operates
	in the same way as factor.

	If lfactor is called with y that is too large, or if x or y
	is not an integer, calc will report an error.  If a 3rd argument
	is given, lfactor will return that value instead.  For example,
	lfactor(1/2,b,c) will return c instead of issuing an error.

	The lfactor function is slower than factor.  If possible factor
	should be used instead of lfactor.

	The builtin isprime(x) will attempt to determine if x is prime.
	As of this release, x must be < 2^32.  With one argument, isprime(x)
	will return an error if x is out of range.  With two arguments,
	isprime(x,y) will not generate an error but instead will return y.

	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".

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: builtin.end,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/builtin.end,v $
##
## Under source code control:	1995/07/10 01:17:53
## File existed as early as:	1995
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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.


    define a function
    -----------------
    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()
		    define printnum(a, n, p)
		    {
			if (p == 0) {
			    print a: "^": n, "=", a^n;
			} else {
			    print a: "^": n, "mod", p, "=", pmod(a,n,p);
			}
		    }


    read calc commands
    ------------------
    read filename
    read -once filename
	    This reads definitions from the specified calc resource 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.

	    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.

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

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

	    If the -m mode disallows opening of files for reading,
	    this command will be disabled.


    write calc commands
    -------------------
    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.

	    If the -m mode disallows opening of files for writing,
	    this command will be disabled.


    quit or exit
    ------------
    quit
    quit string
    exit
    exit string
	    The action of these commands depends on where they are used.
	    At the interactive level, they will cause calc it edit.
	    This is the normal way to leave the calculator.  In any
	    other use, they will stop 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.

	    Exit is an alias for quit.

	    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 (! isnum(n))
			    quit "non-numeric argument";
			if (n < 0)
			    quit "Negative argument";
			return sqrt(n);
		    }

	    See 'more information about abort and quit' below for
	    more information.



    abort
    -----
    abort
    abort string
	    This command behaves like QUIT except that it will attempt
	    to return to the interactive level if permitted, otherwise
	    calc exit.

	    See 'more information about abort and quit' below for
	    more information.


    change current directory
    ------------------------
    cd
    cd dir
	    Change the current directory to 'dir'.  If 'dir' is ommitted,
	    change the current directory to the home directory, if $HOME
	    is set in the environment.


    show information
    ----------------
    show item
	    This command displays some information where 'item' is
	    one of the following:

		    blocks		unfreed named blocks
		    builtin		built in functions
		    config		config parameters and values
		    constants		cache of numeric constants
		    custom		custom functions if calc -C was used
		    errors		new error-values created
		    files		open files, file position and sizes
		    function		user-defined functions
		    globaltypes		global variables
		    objfunctions	possible object functions
		    objtypes		defined objects
		    opcodes func	internal opcodes for function `func'
		    sizes		size in octets of calc value types
		    realglobals		numeric global variables
		    statics		unscoped static variables
		    numbers		calc number cache
		    redcdata		REDC data defined
		    strings		calc string cache
		    literals		calc literal cache

	    Only the first 4 characters of item are examined, so:

		    show globals
		    show global
		    show glob

	    do the same thing.


    calc help
    ---------
    help
    help name
	    This displays a help related to 'name' or general
	    help of none is given.


    =-=


    more information about abort and quit
    =====================================

    Consider the following calc file called myfile.cal:

	print "start of myfile.cal";
	define q() {quit "quit from q()"; print "end of q()"}
	define a() {abort "abort from a()"}
	x = 3;
	{print "start #1"; if (x > 1) q()} print "after #1";
	{print "start #2"; if (x > 1) a()} print "after #2";
	{print "start #3"; if (x > 1) quit "quit from 3rd statement"}
	print "end of myfile.cal";

    The command:

	calc read myfile

    will produce:

	q() defined
	a() defined
	start statment #1
	quit from q()
	after statment #1
	start statment #2
	abort from a()

    The QUIT within the q() function prevented the ``end of q()''
    statement from being evaluated.  This QUIT command caused
    control to be returned to just after the place where q()
    was called.

    Notice that unlike QUIT, the ABORT inside function a() halts
    the processing of statements from the input source (myfile.cal).
    Because calc was not interactive, ABORT causes calc to exit.

    The command:

	calc -i read myfile

    will produce:

	q() defined
	a() defined
	start statment #1
	quit from q()
	after statment #1
	start statment #2
	abort from a()
	>		<==== calc interactive prompt

    because the '-i' calc causes ABORT to drop into an
    interactive prompt.	 However typing a QUIT or ABORT
    at the interactive prompt level will always calc to exit,
    even when calc is invoked with '-i'.

    Also observe that both of these commands:

	cat myfile.cal | calc
	cat myfile.cal | calc -i

    will produce:

	q() defined
	a() defined
	start statment #1
	quit from q()
	after statment #1
	start statment #2
	abort from a()

    The ABORT inside function a() halts the processing of statements
    from the input source (standard input).  Because standard input
    is not a terminal, using '-i' does not force it to drop into
    an interactive prompt.

    If one were to type in the contents of myfile.cal interactively,
    calc will produce:

	> print "start of myfile.cal";
	start of myfile.cal
	> define q() {quit "quit from q()"; print "end of q()"}
	q() defined
	> define a() {abort "abort from a()"}
	a() defined
	> x = 3;
	> {print "start #1"; if (x > 1) q()} print "after #1";
	start statment #1
	quit from q()
	after statment #1
	> {print "start #2"; if (x > 1) a()} print "after #2";
	start statment #2
	abort from a()
	> {print "start #3"; if (x > 1) quit "quit from 3rd statement"}
	start #3
	quit from 3rd statement

    The ABORT from within the a() function returned control to
    the interactive level.

    The QUIT (after the if (x > 1) ...) will cause calc to exit
    because it was given at the interactive prompt level.


    =-=


    Also see the help topic:

	    statement	    flow control and declaration statements
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: command,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/command,v $
##
## Under source code control:	1991/07/21 04:37:17
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* config
*************

Configuration parameters

    Configuration parameters affect how the calculator performs certain
    operations.	 Among features that are controlled by these parameters
    are the accuracy of some calculations, the displayed format of results,
    the choice from possible alternative algorithms, and whether or not
    debugging information is displayed.	 The parameters are
    read or set using the "config" built-in function; they remain in effect
    until their values are changed by a config or equivalent instruction.
    The following parameters can be specified:

	    "all"		all configuration values listed below

	    "trace"		turns tracing features on or off
	    "display"		sets number of digits in prints.
	    "epsilon"		sets error value for transcendentals.
	    "maxprint"		sets maximum number of elements printed.
	    "mode"		sets printout mode.
	    "mode2"		sets 2nd base 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
	    "quomod"		sets rounding mode for quomod
	    "quo"		sets rounding mode for //, default for quo
	    "mod"		sets "rounding" mode for %, default for mod
	    "sqrt"		sets rounding mode for sqrt
	    "appr"		sets rounding mode for appr
	    "cfappr"		sets rounding mode for cfappr
	    "cfsim"		sets rounding mode for cfsim
	    "round"		sets rounding mode for round and bround
	    "outround"		sets rounding mode for printing of numbers
	    "leadzero"		enables/disables printing of 0 as in 0.5
	    "fullzero"		enables/disables padding zeros as in .5000
	    "maxscan"		maximum number of scan errors before abort
	    "prompt"		default interactive prompt
	    "more"		default interactive multi-line input prompt
	    "blkmaxprint"	number of block octets to print, 0 means all
	    "blkverbose"	TRUE=>print all lines, FALSE=>skip duplicates
	    "blkbase"		block output base
	    "blkfmt"		block output format
	    "calc_debug"	controls internal calc debug information
	    "resource_debug"	controls resource file debug information
	    "user_debug"	for user defined debug information
	    "verbose_quit"	TRUE=>print message on empty quit or abort
	    "ctrl_d"		The interactive meaning of ^D (Control D)
	    "program"		Read-only calc program or shell script path
	    "basename"		Read-only basename of the program value
	    "windows"		Read-only indicator of MS windows
	    "cygwin"		TRUE=>calc compiled with cygwin, Read-only
	    "compile_custom"	TRUE=>calc was compiled with custom functions
	    "allow_custom"	TRUE=>custom functions are enabled
	    "version"		Read-only calc version

    The "all" config value allows one to save/restore the configuration
    set of values.  The return of:

	    config("all")

    is a CONFIG type which may be used as the 2rd arg in a later call.
    One may save, modify and restore the configuration state as follows:

	    oldstate = config("all")
	    ...
	    config("tab", 0)
	    config("mod", 10)
	    ...
	    config("all", oldstate)

    This save/restore method is useful within functions.
    It allows functions to control their configuration without impacting
    the calling function.

    There are two configuration state aliases that may be set.	To
    set the backward compatible standard configuration:

	    config("all", "oldstd")

    The "oldstd" will restore the configuration to the default at startup.

    A new configuration that some people prefer may be set by:

	    config("all", "newstd")

    The "newstd" is not backward compatible with the historic
    configuration.  Even so, some people prefer this configuration
    and place the config("all", "newstd") command in their CALCRC
    startup files; newstd may also be established by invoking calc
    with the flag -n.

    The following are synonyms for true:

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

    The following are synonyms for false:

	    "off"
	    "false"
	    "f"
	    "no"
	    "n"
	    "unset"
	    "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


Detailed config descriptions

    =-=

    config("trace", bitflag)

    When nonzero, the "trace" parameter activates one or more features
    that may be useful for debugging.  These features correspond to
    powers of 2 which contribute additively to config("trace"):

	1: opcodes are displayed as functions are evaluated

	2: disables the inclusion of debug lines in opcodes for functions
	   whose definitions are introduced with a left-brace.

	4: the number of links for real and complex numbers are displayed
	   when the numbers are printed; for real numbers "#" or for
	   complex numbers "##", followed by the number of links, are
	   printed immediately after the number.

	8: the opcodes for a new functions are displayed when the function
	   is successfully defined.

    See also resource_debug, calc_debug and user_debug below for more
    debug levels.

    =-=

    config("display", int)

    The "display" parameter specifies the maximum number of digits after
    the decimal point to be printed in real or exponential mode in
    normal unformatted printing (print, strprint, fprint) or in
    formatted printing (printf, strprintf, fprintf) when precision is not
    specified.	The initial value for oldstd is 20, for newstd 10.
    The parameter may be changed to the value d by either
    config("display", d) or by display (d).  This parameter does not change
    the stored value of a number.  Where rounding is necessary to
    display up to d decimal places, the type of rounding to be used is
    controlled by config("outround").

    =-=

    config("epsilon", real)
    epsilon(real)

    The "epsilon" parameter specifies the default accuracy for the
    calculation of functions for which exact values are not possible or
    not desired.  For most functions, the

		remainder = exact value - calculated value

    has absolute value less than epsilon, but, except when the sign of
    the remainder is controlled by an appropriate parameter, the
    absolute value of the remainder usually does not exceed epsilon/2.
    Functions which require an epsilon value accept an
    optional argument which overrides this default epsilon value for
    that single call.  The value v can be assigned to the "epsilon"
    parameter by either config("epsilon", v) or epsilon(v); each of
    these functions return the current epsilon value; config("epsilon")
    or epsilon() returns but does not change the epsilon value.
    For the transcendental functions and the functions sqrt() and
    appr(), the calculated value is always a multiple of epsilon.

    =-=

    config("mode", "mode_string")
    config("mode2", "mode_string")

    The "mode" parameter is a string specifying the mode for printing of
    numbers by the unformatted print functions, and the default
    ("%d" specifier) for formatted print functions.  The initial mode
    is "real".	The available modes are:

	  config("mode")	meaning				equivalent
	      string						base() call

	    "binary"		base 2 fractions		base(2)
	    "bin"

	    "octal"		base 8 fractions		base(8)
	    "oct"

	    "real"		base 10 floating point		base(10)
	    "float"
	    "default"

	    "integer"		base 10 integer			base(-10)
	    "int"

	    "hexadecimal"	base 16 fractions		base(16)
	    "hex"

	    "fraction"		base 10 fractions		base(1/3)
	    "frac"

	    "scientific"	base 10 scientific notation	base(1e20)
	    "sci"
	    "exp"

    Where multiple strings are given, the first string listed is what
    config("mode") will return.

    The "mode2" controls the double base output.  When set to a value
    other than "off", calc outputs files in both the "base" mode as
    well as the "base2" mode.  The "mode2" value may be any of the
    "mode" values with the addition of:

	    "off"		disable 2nd base output mode	base2(0)

    The base() builtin function sets and returns the "mode" value.
    The base2() builtin function sets and returns the "mode2" value.

    The default "mode" is "real".  The default "mode2" is "off".

    =-=

    config("maxprint", int)

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

    =-=

    config("mul2", int)
    config("sq2", int)

    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.

    =-=

    config("pow2", int)

    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.

    =-=

    config("redc2", int)

    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.

    =-=

    config("tilde", boolean)

    Config("tilde") controls whether or not a leading tilde ('~') is
    printed to indicate that a number has not been printed exactly
    because the number of decimal digits required would exceed the
    specified maximum number.  The initial "tilde" value is 1.

    =-=

    config("tab", boolean)

    Config ("tab") controls the printing of a tab before results
    automatically displayed when working interactively.	 It does not
    affect the printing by the functions print, printf, etc.  The initial
    "tab" value is 1.

    =-=

    config("quomod", bitflag)
    config("quo", bitflag)
    config("mod", bitflag)
    config("sqrt", bitflag)
    config("appr", bitflag)
    config("cfappr", bitflag)
    config("cfsim", bitflag)
    config("outround", bitflag)
    config("round", bitflag)

    The "quomod", "quo", "mod", "sqrt", "appr", "cfappr", "cfsim", and
    "round" control the way in which any necessary rounding occurs.
    Rounding occurs when for some reason, a calculated or displayed
    value (the "approximation") has to differ from the "true value",
    e.g. for quomod and quo, the quotient is to be an integer, for sqrt
    and appr, the approximation is to be a multiple of an explicit or
    implicit "epsilon", for round and bround (both controlled by
    config("round")) the number of decimal places or fractional bits
    in the approximation is limited.  Zero value for any of these
    parameters indicates that the true value is greater than the approximation,
    i.e. the rounding is "down", or in the case of mod, that the
    residue has the same sign as the divisor.  If bit 4 of the
    parameter is set, the rounding of to the nearest acceptable candidate
    when this is uniquely determined; in the remaining ambiguous cases,
    the type of rounding is determined by the lower bits of the parameter
    value.  If bit 3 is set, the rounding for quo, appr and sqrt,
    is to the nearest even integer or the nearest even multiple of epsilon,
    and for round to the nearest even "last decimal place".  The effects
    of the 3 lowest bits of the parameter value are as follows:

	Bit 0: Unconditional reversal (down to up, even to odd, etc.)
	Bit 1: Reversal if the exact value is negative
	Bit 2: Reversal if the divisor or epsilon is negative

    (Bit 2 is irrelevant for the functions round and bround since the
    equivalent epsilon (a power of 1/10 or 1/2) is always positive.)

    For quomod, the quotient is rounded to an integer value as if
    evaluating quo with config("quo") == config("quomod").  Similarly,
    quomod and mod give the same residues if config("mod") == config("quomod").

    For the sqrt function, if bit 5 of config("sqrt") is set, the exact
    square-root is returned when this is possible; otherwise the
    result is rounded to a multiple of epsilon as determined by the
    five lower order bits.  Bit 6 of config("sqrt") controls whether the
    principal or non-principal square-root is returned.

    For the functions cfappr and cfsim, whether the "rounding" is down
    or up, etc. is controlled by the appropriate bits of config("cfappr")
    and config("cfsim") as for quomod, quo, etc.

    The "outround" parameter determines the type of rounding to be used
    by the various kinds of printing to the output: bits 0, 1, 3 and 4
    are used in the same way as for the functions round and bround.

    =-=

    config("leadzero", bool)

    The "leadzero" parameter controls whether or not a 0 is printed
    before the decimal point in non-zero fractions with absolute value
    less than 1, e.g. whether 1/2 is printed as 0.5 or .5.   The
    initial value is 0, corresponding to the printing .5.

    =-=

    config("fullzero", bool)

    The "fullzero" parameter controls whether or not in decimal floating-
    point printing, the digits are padded with zeros to reach the
    number of digits specified by config("display") or by a precision
    specification in formatted printing.  The initial value for this
    parameter is 0, so that, for example, if config("display") >= 2,
    5/4 will print in "real" mode as 1.25.

    =-=

    config("maxscan", int)

    The maxscan value controls how many scan errors are allowed
    before the compiling phase of a computation is aborted.  The initial
    value of "maxscan" is 20.  Setting maxscan to 0 disables this feature.

    =-=

    config("prompt", str)

    The default prompt when in interactive mode is "> ".  One may change
    this prompt to a more cut-and-paste friendly prompt by:

	    config("prompt", "; ")

    On windowing systems that support cut/paste of a line, one may
    cut/copy an input line and paste it directly into input.  The
    leading ';' will be ignored.

    =-=

    config("more", str)

    When inside multi-line input, the more prompt is used.  One may
    change it by:

	    config("more", ";; ")

    =-=

    config("blkmaxprint", int)

    The "blkmaxprint" config value limits the number of octets to print
    for a block.  A "blkmaxprint" of 0 means to print all octets of a
    block, regardless of size.

    The default is to print only the first 256 octets.

    =-=

    config("blkverbose", bool)

    The "blkverbose" determines if all lines, including duplicates
    should be printed.	If TRUE, then all lines are printed.  If false,
    duplicate lines are skipped and only a "*" is printed in a style
    similar to od.  This config value has not meaning if "blkfmt" is "str".

    The default value for "blkverbose" is FALSE: duplicate lines are
    not printed.

    =-=

    config("blkbase", "blkbase_string")

    The "blkbase" determines the base in which octets of a block
    are printed.  Possible values are:

	"hexadecimal"		Octets printed in 2 digit hex
	"hex"
	"default"

	"octal"			Octets printed in 3 digit octal
	"oct"

	"character"		Octets printed as chars with non-printing
	"char"			    chars as \123 or \n, \t, \r

	"binary"		Octets printed as 0 or 1 chars
	"bin"

	"raw"			Octets printed as is, i.e. raw binary
	"none"

    Where multiple strings are given, the first string listed is what
    config("blkbase") will return.

    The default "blkbase" is "hexadecimal".

    =-=

    config("blkfmt", "blkfmt_string")

    The "blkfmt" determines for format of how block are printed:

	"lines"		print in lines of up to 79 chars + newline
	"line"

	"strings"	print as one long string
	"string"
	"str"

	"od_style"	print in od-like format, with leading offset,
	"odstyle"	   followed by octets in the given base
	"od"

	"hd_style"	print in hex dump format, with leading offset,
	"hdstyle"	   followed by octets in the given base, followed
	"hd"		   by chars or '.' if no-printable or blank
	"default"

    Where multiple strings are given, the first string listed is what
    config("blkfmt") will return.

    The default "blkfmt" is "hd_style".

    =-=

    config("calc_debug", bitflag)

    The "calc_debug" is intended for controlling internal calc routines
    that test its operation, or collect or display information that
    might be useful for debug purposes.	 Much of the output from these
    will make sense only to calc wizards.   Zero value (the default for
    both oldstd and newstd) of config("resource_debug") corresponds to
    switching off all these routines.  For nonzero value, particular
    bits currently have the following meanings:

	n		Meaning of bit n of config("calc_debug")

	0	outputs shell commands prior to execution

	1	outputs currently active functions when a quit instruction
		is executed

	2	some details of shs, shs1 and md5 hash states are included
		in the output when these are printed

	3	when a function constructs a block value, tests are
		made that the result has the properties required for use of
		that block, e.g. that the pointer to the start of the
		block is not NULL, and that its "length" is not negative.
		A failure will result in a runtime error.

	4	Report on changes to the state of stdin as well as changes
		to internal variables that control the setting and restoring
		of stdin.

	5	Report on changes to the run state of calc.

	6	Report on rand() subtractive 100 shuffle generator issues.

    Bits >= 7 are reserved for future use and should not be used at this time.

    By default, "calc_debug" is 0.  The initial value may be overridden
    by the -D command line option.

    =-=

    config("resource_debug", bitflag)
    config("lib_debug", bitflag)

    The "resource_debug" parameter is intended for controlling the possible
    display of special information relating to functions, objects, and
    other structures created by instructions in calc scripts.
    Zero value of config("resource_debug") means that no such information
    is displayed.  For other values, the non-zero bits which currently
    have meanings are as follows:

	n		Meaning of bit n of config("resource_debug")

	0	When a function is defined, redefined or undefined at
		interactive level, a message saying what has been done
		is displayed.

	1	When a function is defined, redefined or undefined during
		the reading of a file, a message saying what has been done
		is displayed.

	2	Show func will display more information about a functions
		arguments and argument summary information.

	3	During execution, allow calc standard resource files
		to output additional debugging information.

    The value for config("resource_debug") in both oldstd and newstd is 3,
    but if calc is invoked with the -d flag, its initial value is zero.
    Thus, if calc is started without the -d flag, until config("resource_debug")
    is changed, a message will be output when a function is defined
    either interactively or during the reading of a file.

    The name config("lib_debug") is equivalent to config("resource_debug")
    and is included for backward compatibility.

    By default, "resource_debug" is 3.	The -d flag changes this default to 0.
    The initial value may be overridden by the -D command line option.

    =-=

    config("user_debug", int)

    The "user_debug" is provided for use by users.  Calc ignores this value
    other than to set it to 0 by default (for both "oldstd" and "newstd").
    No calc code or standard resource should change this value.	 Users
    should feel free to use it in any way.   In particular they may
    use particular bits for special purposes as with "calc_debug", or
    they may use it to indicate a debug level with larger values
    indicating more stringent and more informative tests with presumably
    slower operation or more memory usage, and a particular value (like
    -1 or 0) corresponding to "no tests".

    By default, "user_debug" is 0.  The initial value may be overridden
    by the -D command line option.

    =-=

    config("verbose_quit", bool)

    The "verbose_quit" controls the print of the message:

	quit or abort executed

    when a non-interactive quit or abort without an argument is encountered.
    A quit of abort without an argument does not display a message when
    invoked at the interactive level.

    By deafult, "verbose_quit" is false.

    =-=

    config("ctrl_d", "ctrl_d_string")

    For calc that is using the calc binding (not GNU-readline) facility:

	The "ctrl_d" controls the interactive meaning of ^D (Control D):

	    "virgin_eof"  If ^D is the only character that has been typed
	    "virgineof"	  on a line, then calc will exit.  Otherwise ^D
	    "virgin"	  will act according to the calc binding, which
	    "default"	  by default is a Emacs-style delete-char.

	    "never_eof"	  The ^D never exits calc and only acts according
	    "nevereof"	  calc binding, which by default is a Emacs-style
	    "never"	  delete-char.

	    "empty_eof"	  The ^D always exits calc if typed on an empty line.
	    "emptyeof"	  This condition occurs when ^D either the first
	    "empty"	  character typed, or when all other characters on
			  the line have been removed (say by deleting them).

	Where multiple strings are given, the first string listed is what
	config("ctrl_d") will return.

	Note that config("ctrl_d") actually controls each and every character
	that is bound to ``delete_char''.  By default, ``delete_char'' is
	Control D.  Any character(s) bound to ``delete_char'' will cause calc
	to exit (or not exit) as directed by config("ctrl_d").

	See the ``binding'' help for information on the default calc bindings.

	The default "ctrl_d", without GNU-readline is "virgin_eof".

    For calc that was compiled with the GNU-readline facility:

	The "ctrl_d" controls the interactive meaning of ^D (Control D):

	    "virgin_eof"  Same as "empty_eof"
	    "virgineof"
	    "virgin"
	    "default"

	    "never_eof"	  The ^D never exits calc and only acts according
	    "nevereof"	  calc binding, which by default is a Emacs-style
	    "never"	  delete-char.

	    "empty_eof"	  The ^D always exits calc if typed on an empty line.
	    "emptyeof"	  This condition occurs when ^D either the first
	    "empty"	  character typed, or when all other characters on

	Where multiple strings are given, the first string listed is what
	config("ctrl_d") will return.

	The default "ctrl_d", with GNU-readline is effectively "empty_eof".

	Literally it is "virgin_eof", but since "virgin_eof" is the
	same as "empty_eof", the default is effectively "empty_eof".

    Emacs users may find the default behavior objectionable, particularly
    when using the GNU-readline facility.  Such users may want to add the line:

	config("ctrl_d", "never_eof"),;

    to their ~/.calcrc startup file to prevent ^D from causing calc to exit.

    =-=

    config("program")		<== NOTE: This is a read-only config value

    The full path to the calc program, or the calc shell script can be
    obtained by:

	config("program")

    This config parameter is read-only and cannot be set.

    =-=

    config("basename")		<== NOTE: This is a read-only config value

    The calc program, or the calc shell script basename can be obtained by:

	config("basename")

    The config("basename") is the config("program") without any leading
    path.  If config("program") has a / in it, config("basename") is
    everything after the last /, otherwise config("basename") is the
    same as config("program").

    This config parameter is read-only and cannot be set.

    =-=

    config("windows")		<== NOTE: This is a read-only config value

    Returns TRUE if you are running on a MS windows system, false if you
    are running on an operating system that does not hate you.

    This config parameter is read-only and cannot be set.

    =-=

    config("cygwin")		<== NOTE: This is a read-only config value

    Returns TRUE if you calc was compiled with cygwin, false otherwise.

    This config parameter is read-only and cannot be set.

    =-=

    config("compile_custom")	<== NOTE: This is a read-only config value

    Returns TRUE if you calc was compiled with -DCUSTOM.  By default,
    the calc Makefile uses ALLOW_CUSTOM= -DCUSTOM so by default
    config("compile_custom") is TRUE.  If, however, calc is compiled
    without -DCUSTOM, then config("compile_custom") will be FALSE.

    The config("compile_custom") value is only affected by compile
    flags.   The calc -D runtime command line option does not change
    the config("compile_custom") value.

    See also config("allow_custom").

    This config parameter is read-only and cannot be set.

    =-=

    config("allow_custom")	<== NOTE: This is a read-only config value

    Returns TRUE if you custom functions are enabled.  To allow the use
    of custom functions, calc must be compiled with -DCUSTOM (which it
    is by default) AND calc run be run with the -D runtime command line
    option (which it is not by default).

    If config("allow_custom") is TRUE, then custom functions are allowed.
    If config("allow_custom") is FALSE, then custom functions are not
    allowed.

    See also config("compile_custom").

    This config parameter is read-only and cannot be set.

    =-=

    config("version")		<== NOTE: This is a read-only config value

    The version string of the calc program can be obtained by:

	config("version")

    This config parameter is read-only and cannot be set.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.10 $
## @(#) $Id: config,v 29.10 2004/07/27 23:45:52 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/config,v $
##
## Under source code control:	1991/07/21 04:37:17
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* custom
*************

NAME
    custom - custom builtin interface

SYNOPSIS
    custom([custname [, arg ...]])

TYPES
    custname	string
    arg		any

    return	any

DESCRIPTION
    This function will invoke the custom function interface.  Custom
    functions are accessed by the custname argument.  The remainder
    of the args, if any, are passed to the custom function.  The
    custom function may return any value, including null.  Calling
    custom with no args is equivalent to the command 'show custom'.

    In order to use the custom interface, two things must happen:

	1) Calc must be built to allow custom functions.  By default,
	   the master Makefile is shipped with ALLOW_CUSTOM= -DCUSTOM
	   which causes custom functions to be compiled in.

	2) Calc must be invoked with an argument of -C as in:

		calc -C

    In other words, explicit action must be taken in order to
    enable the use of custom functions.	 By default (no -C arg)
    custom functions are compiled in but disabled so that only
    portable calc scripts may be used.

    The main focus for calc is to provide a portable platform for
    multi-precision calculations in a C-like environment.  You should
    consider implementing algorithms in the calc language as a first
    choice.  Sometimes an algorithm requires use of special hardware, a
    non-portable OS or pre-compiled C library.	In these cases a custom
    interface may be needed.

    The custom function interface is intended to make is easy for
    programmers to add functionality that would be otherwise
    un-suitable for general distribution.  Functions that are
    non-portable (machine, hardware or OS dependent) or highly
    specialized are possible candidates for custom functions.

    To add a new custom function requires access to calc source.
    For information on how to add a new custom function, try:

	    help new_custom

    To serve as examples, calc is shipped with a few custom functions.
    If calc if invoked with -C, then either of the following will
    display information about the custom functions that are available:

	    show custom
    or:

	    custom()

    A few resource files that uses these function are also provided
    to serve as usage examples.

    We welcome submissions for new custom functions.  For information
    on how to submit new custom functions for general distribution, see:

	    help contrib

EXAMPLE
    If calc compiled with ALLOW_CUSTOM= (custom disabled):

    > print custom("sysinfo", "baseb")
	    Calc was built with custom functions disabled
    Error 10195

    If calc compiled with ALLOW_CUSTOM= -DCUSTOM and is invoked without -C:

    > print custom("sysinfo", "baseb")
	    Calc must be run with a -C argument to use custom function
    Error 10194

    If calc compiled with ALLOW_CUSTOM= -DCUSTOM and is invoked with -C:

    > print custom("sysinfo", "baseb")
    32

LIMITS
    By default, custom is limited to 100 args.

LINK LIBRARY
    none

SEE ALSO
    custom_cal, new_custom, contrib

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: custom,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/custom,v $
##
## Under source code control:	1997/03/09 16:33:22
## File existed as early as:	1997
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* define
*************

NAME
    define - command keyword to start a function definition

SYNTAX
    define fname([param_1 [= default_1], ...]) = [expr]
    define fname([param_1 [= default_1], ...]) { [statement_1 ... ] }

TYPES
    fname		identifier, not a builtin function name
    param_1, ...	identifiers, no two the same
    default_1, ...	expressions
    expr		expression
    statement_1, ...	statements

DESCRIPTION
    The intention of a function definition is that the identifier fname
    becomes the name of a function which may be called by an expression
    of the form  fname(arg_1, arg_2, ...), where arg_1, arg_2, ... are
    expressions (including possibly blanks, which are treated as
    null values).  Evaluation of the function begins with evaluation
    of arg_1, arg_2, ...; then, in increasing order of i, if arg_i is
    null-valued and  "= default_i" has been included in the definition,
    default_i is evaluated and its value becomes the value of arg_i.
    The instructions in expr or the listed statements are then executed
    with each occurrence of param_i replaced by the value obtained
    for arg_i.

    In a call, arg_i may be preceded by a backquote (`)  to indicate that
    evaluation of arg_i is not to include a final evaluation of an lvalue.
    For example, suppose a function f and a global variable A have been
    defined by:

		define f(x) = (x = 3);
		global mat A[3];

    If g() is  a function that evaluates to 2:

		f(A[g()]);

    assigns the value of A[2] to the parameter x and then assigns the
    value 3 to x:

		f(`A[g()]);

    has essentially the effect of assigning A[2] as an lvalue to x and
    then assigning the value 3 to A[2].  (Very old versions of calc
    achieved the same result by using '&' as in  f(&A[g()]).)

    The number of arguments arg_1, arg_2, ... in a call need not equal the
    number of parameters.  If there are fewer arguments than parameters,
    the "missing" values are assigned the null value.

    In the definition of a function, the builtin function param(n)
    provides a way of referring to the parameters.  If n (which may
    result from evaluating an expreession) is zero, it returns the number
    of arguments in a call to the function, and if 1 <= n <= param(0),
    param(n) refers to the parameter with index n.

    If no error occurs and no quit statement or abort statement is
    encountered during evaluation of the expression or the statements,
    the function call returns a value.  In the expression form, this is
    simply the value of the expression.

    In the statement form, if a return statement is encountered,
    the "return" keyword is to be either immediately followed by an
    expression or by a statement terminator (semicolon or rightbrace);
    in the former case, the expression is evaluated, evaluation of
    the function ceases, and the value obtained for the expression is
    returned as the "value of the function";  in the no-expression case,
    evaluation ceases immediately and the null-value is returned.

    In the expression form of definition, the end of the expression expr
    is to be indicated by either a semicolon or a newline not within
    a part enclosed by parentheses; the definition may extend over
    several physical lines by ending each line with a '\' character or by
    enclosing the expression in parentheses.  In interactive mode, that
    a definition has not been completed is indicated by the continuation
    prompt.   A ctrl-C interrupt at this stage will abort the definition.

    If the expr is omitted from an expression definition, as in:

		define h() = ;

    any call to the function will evaluate the arguments and return the
    null value.

    In the statement form, the definition ends when a matching right
    brace completes the "block" started by the initial left brace.
    Newlines within the block are treated as white space; statements
    within the block end with a ';' or a '}' matching an earlier '{'.

    If a function with name fname had been defined earlier, the old
    definition has no effect on the new definition, but if the definition
    is completed successfully, the new definition replaces the old one;
    otherwise the old definition is retained.  The number of parameters
    and their names in the new definiton may be quite different from
    those in the old definition.

    An attempt at a definition may fail because of scanerrors as the
    definition is compiled.  Common causes of these are: bad syntax,
    using identifiers as names of variables not yet defined.  It is
    not a fault to have in the definition a call to a function that has
    not yet been defined; it is sufficient that the function has been
    defined when a call is made to the function.

    After fname has been defined, the definition may be removed by the command:

		undefine fname

    The definitions of all user-defined functions may be removed by:

		undefine *

    If bit 0 of config("resource_debug") is set and the define command is
    at interactive level, a message saying that fname has been defined
    or redefined is displayed.  The same message is displayed if bit 1
    of config("resource_debug") is set and the define command is read
    from a file.

    The identifiers used for the parameters in a function definition do
    not form part of the completed definition.  For example,

	define f(a,b) = a + b;
	define g(alpha, beta) = alpha + beta;

    result in identical code for the functions f, g.

    If config("trace") & 8 is nonzero, the opcodes of a newly defined
    function are displayed on completion of its definition, parameters
    being specified by names used in the definition.  For example:

	> config("trace", 8),
	> define f(a,b) = a + b
	0: PARAMADDR a
	2: PARAMADDR b
	4: ADD
	5: RETURN
	f(a,b) defined

    The opcodes may also be displayed later using the show opcodes command;
    parameters will be specified by indices instead of by names.  For example:

	> show opco f
	0: PARAMADDR 0
	2: PARAMADDR 1
	4: ADD
	5: RETURN

    When a function is defined by the statement mode, the opcodes normally
    include DEBUG opcodes which specify statement boundaries at which
    SIGINT interruptions are likely to be least risky.  Inclusion of
    the DEBUG opcodes is disabled if config("trace") & 2 is nonzero.
    For details, see help interrupt.

    While config("trace") & 1 is nonzero, the opcodes are displayed as
    they are being evaluated.  The current function is identified by its
    name, or "*" in the case of a command-line and "**" in the case of
    an eval(str) evaluation.

    When a function is called, argument values may be of any type for
    which the operations and any functions used within the body of the
    definition can be executed.  For example, whatever the intention at
    the time they were defined, the functions f1(), f2() defined above
    may be called with integer, fractional, or complex-number values, or
    with both arguments strings, or under some compatibility conditions,
    matrices or objects.

EXAMPLE
    > define f(a,b) = 2*a + b;
    > define g(alpha, beta)
    >> {
    >>	   local a, pi2;
    >>
    >>	   pi2 = 2 * pi();
    >>	   a = sin(alpha % pi2);
    >>	   if (a > 0.0) {
    >>	       return a*beta;
    >>	   }
    >>	   if (beta > 0.0) {
    >>	       a *= cos(-beta % pi2);
    >>	   }
    >>	   return a;
    >> }

LIMITS
    The number of arguments in a function-call cannot exceed 100.

LIBRARY
    none

SEE ALSO
    param, variable, undefine, show

## Copyright (C) 2000  David I. Bell, Landon Curt Noll and Ernest Bowen
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.3 $
## @(#) $Id: define,v 29.3 2000/07/17 15:36:26 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/define,v $
##
##
## Under source code control:	1991/07/21 04:37:18
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* environment
*************

Environment variables

    CALCPATH

	A :-separated list of directories used to search for
	resource filenames (*.cal files) that do not begin with
	/, ./ or ~.

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

		    .:./cal:~/cal:${CALC_SHAREDIR}:${CUSTOMCALDIR}

	which is usually:

		    .:./cal:~/cal:/usr/share/calc:/usr/share/calc/custom

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

	The CALCBINDINGS file searches the CALCPATH as well.


    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:

		    ${CALC_SHAREDIR}/startup:~/.calcrc:./.calcinit

	which is usually:

		    /usr/share/calc/startup:~/.calcrc:./.calcinit

	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:

		    bindings

	The bindings file is searched along the CALCPATH.  Unlike
	the READ command, a .cal extension is not added.

	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.

	NOTE: If calc was compiled with GNU-readline support, the
	      CALCBINDINGS facility is ignored and the standard
	      readline mechanisms (see readline(3)) are used.

    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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.3 $
## @(#) $Id: environment,v 29.3 2004/07/26 07:10:43 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/environment,v $
##
## Under source code control:	1991/07/23 05:47:25
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: expression,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/expression,v $
##
## Under source code control:	1991/07/21 04:37:18
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* errorcodes
*************

Calc generated error codes (see the error help file):

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: errorcodes.hdr,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/errorcodes.hdr,v $
##
## Under source code control:	1995/12/18 03:19:11
## File existed as early as:	1995
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/
    10001	Division by zero
    10002	Indeterminate (0/0)
    10003	Bad arguments for +
    10004	Bad arguments for binary -
    10005	Bad arguments for *
    10006	Bad arguments for /
    10007	Bad argument for unary -
    10008	Bad argument for squaring
    10009	Bad argument for inverse
    10010	Bad argument for ++
    10011	Bad argument for --
    10012	Bad argument for int
    10013	Bad argument for frac
    10014	Bad argument for conj
    10015	Bad first argument for appr
    10016	Bad second argument for appr
    10017	Bad third argument for appr
    10018	Bad first argument for round
    10019	Bad second argument for round
    10020	Bad third argument for round
    10021	Bad first argument for bround
    10022	Bad second argument for bround
    10023	Bad third argument for bround
    10024	Bad first argument for sqrt
    10025	Bad second argument for sqrt
    10026	Bad third argument for sqrt
    10027	Bad first argument for root
    10028	Bad second argument for root
    10029	Bad third argument for root
    10030	Bad argument for norm
    10031	Bad first argument for << or >>
    10032	Bad second argument for << or >>
    10033	Bad first argument for scale
    10034	Bad second argument for scale
    10035	Bad first argument for ^
    10036	Bad second argument for ^
    10037	Bad first argument for power
    10038	Bad second argument for power
    10039	Bad third argument for power
    10040	Bad first argument for quo or //
    10041	Bad second argument for quo or //
    10042	Bad third argument for quo
    10043	Bad first argument for mod or %
    10044	Bad second argument for mod or %
    10045	Bad third argument for mod
    10046	Bad argument for sgn
    10047	Bad first argument for abs
    10048	Bad second argument for abs
    10049	Scan error in argument for eval
    10050	Non-simple type for str
    10051	Non-real epsilon for exp
    10052	Bad first argument for exp
    10053	Non-file first argument for fputc
    10054	Bad second argument for fputc
    10055	File not open for writing for fputc
    10056	Non-file first argument for fgetc
    10057	File not open for reading for fgetc
    10058	Non-string arguments for fopen
    10059	Unrecognized mode for fopen
    10060	Non-file first argument for freopen
    10061	Non-string or unrecognized mode for freopen
    10062	Non-string third argument for freopen
    10063	Non-file argument for fclose
    10064	Non-file argument for fflush
    10065	Non-file first argument for fputs
    10066	Non-string argument after first for fputs
    10067	File not open for writing for fputs
    10068	Non-file argument for fgets
    10069	File not open for reading for fgets
    10070	Non-file first argument for fputstr
    10071	Non-string argument after first for fputstr
    10072	File not open for writing for fputstr
    10073	Non-file first argument for fgetstr
    10074	File not open for reading for fgetstr
    10075	Non-file argument for fgetline
    10076	File not open for reading for fgetline
    10077	Non-file argument for fgetfield
    10078	File not open for reading for fgetfield
    10079	Non-file argument for rewind
    10080	Non-integer argument for files
    10081	Non-string fmt argument for fprint
    10082	Stdout not open for writing to ???
    10083	Non-file first argument for fprintf
    10084	Non-string second (fmt) argument for fprintf
    10085	File not open for writing for fprintf
    10086	Non-string first (fmt) argument for strprintf
    10087	Error in attempting strprintf ???
    10088	Non-file first argument for fscan
    10089	File not open for reading for fscan
    10090	Non-string first argument for strscan
    10091	Non-file first argument for fscanf
    10092	Non-string second (fmt) argument for fscanf
    10093	Non-lvalue argument after second for fscanf
    10094	File not open for reading or other error for fscanf
    10095	Non-string first argument for strscanf
    10096	Non-string second (fmt) argument for strscanf
    10097	Non-lvalue argument after second for strscanf
    10098	Some error in attempting strscanf ???
    10099	Non-string first (fmt) argument for scanf
    10100	Non-lvalue argument after first for scanf
    10101	Some error in attempting scanf ???
    10102	Non-file argument for ftell
    10103	File not open or other error for ftell
    10104	Non-file first argument for fseek
    10105	Non-integer or negative second argument for fseek
    10106	File not open or other error for fseek
    10107	Non-file argument for fsize
    10108	File not open or other error for fsize
    10109	Non-file argument for feof
    10110	File not open or other error for feof
    10111	Non-file argument for ferror
    10112	File not open or other error for ferror
    10113	Non-file argument for ungetc
    10114	File not open for reading for ungetc
    10115	Bad second argument or other error for ungetc
    10116	Exponent too big in scanning
    10117	E_ISATTY1 is no longer used
    10118	E_ISATTY2 is no longer used
    10119	Non-string first argument for access
    10120	Bad second argument for access
    10121	Bad first argument for search
    10122	Bad second argument for search
    10123	Bad third argument for search
    10124	Bad fourth argument for search
    10125	Cannot find fsize or fpos for search
    10126	File not readable for search
    10127	Bad first argument for rsearch
    10128	Bad second argument for rsearch
    10129	Bad third argument for rsearch
    10130	Bad fourth argument for rsearch
    10131	Cannot find fsize or fpos for rsearch
    10132	File not readable for rsearch
    10133	Too many open files
    10134	Attempt to rewind a file that is not open
    10135	Bad argument type for strerror
    10136	Index out of range for strerror
    10137	Bad epsilon for cos
    10138	Bad first argument for cos
    10139	Bad epsilon for sin
    10140	Bad first argument for sin
    10141	Non-string argument for eval
    10142	Bad epsilon for arg
    10143	Bad first argument for arg
    10144	Non-real argument for polar
    10145	Bad epsilon for polar
    10146	Non-integral argument for fcnt
    10147	Non-variable first argument for matfill
    10148	Non-matrix first argument-value for matfill
    10149	Non-matrix argument for matdim
    10150	Non-matrix argument for matsum
    10151	E_ISIDENT is no longer used
    10152	Non-matrix argument for mattrans
    10153	Non-two-dimensional matrix for mattrans
    10154	Non-matrix argument for det
    10155	Matrix for det not of dimension 2
    10156	Non-square matrix for det
    10157	Non-matrix first argument for matmin
    10158	Non-positive-integer second argument for matmin
    10159	Second argument for matmin exceeds dimension
    10160	Non-matrix first argument for matmin
    10161	Second argument for matmax not positive integer
    10162	Second argument for matmax exceeds dimension
    10163	Non-matrix argument for cp
    10164	Non-one-dimensional matrix for cp
    10165	Matrix size not 3 for cp
    10166	Non-matrix argument for dp
    10167	Non-one-dimensional matrix for dp
    10168	Different-size matrices for dp
    10169	Non-string argument for strlen
    10170	Non-string argument for strcat
    10171	Non-string first argument for strcat
    10172	Non-non-negative integer second argument for strcat
    10173	Bad argument for char
    10174	Non-string argument for ord
    10175	Non-list-variable first argument for insert
    10176	Non-integral second argument for insert
    10177	Non-list-variable first argument for push
    10178	Non-list-variable first argument for append
    10179	Non-list-variable first argument for delete
    10180	Non-integral second argument for delete
    10181	Non-list-variable argument for pop
    10182	Non-list-variable argument for remove
    10183	Bad epsilon argument for ln
    10184	Non-numeric first argument for ln
    10185	Non-integer argument for error
    10186	Argument outside range for error
    10187	Attempt to eval at maximum input depth
    10188	Unable to open string for reading
    10189	First argument for rm is not a non-empty string
    10190	Unable to remove a file
    10191	Operation allowed because calc mode disallows read operations
    10192	Operation allowed because calc mode disallows write operations
    10193	Operation allowed because calc mode disallows exec operations
    10194	Unordered arguments for min
    10195	Unordered arguments for max
    10196	Unordered items for minimum of list
    10197	Unordered items for maximum of list
    10198	Size undefined for argument type
    10199	Calc must be run with a -C argument to use custom function
    10200	Calc was built with custom functions disabled
    10201	Custom function unknown, try: show custom
    10202	Non-integral length for block
    10203	Negative or too-large length for block
    10204	Non-integral chunksize for block
    10205	Negative or too-large chunksize for block
    10206	Named block does not exist for blkfree
    10207	Non-integral id specification for blkfree
    10208	Block with specified id does not exist
    10209	Block already freed
    10210	No-realloc protection prevents blkfree
    10211	Non-integer argument for blocks
    10212	Non-allocated index number for blocks
    10213	Non-integer or negative source index for copy
    10214	Source index too large for copy
    10215	E_COPY3 is no longer used
    10216	Non-integer or negative number for copy
    10217	Number too large for copy
    10218	Non-integer or negative destination index for copy
    10219	Destination index too large for copy
    10220	Freed block source for copy
    10221	Unsuitable source type for copy
    10222	Freed block destinction for copy
    10223	Unsuitable destination type for copy
    10224	Incompatible source and destination for copy
    10225	No-copy-from source variable
    10226	No-copy-to destination variable
    10227	No-copy-from source named block
    10228	No-copy-to destination named block
    10229	No-relocation destination for copy
    10230	File not open for copy
    10231	fseek or fsize failure for copy
    10232	fwrite error for copy
    10233	fread error for copy
    10234	Non-variable first argument for protect
    10235	Non-integer second argument for protect
    10236	Out-of-range second argument for protect
    10237	No-copy-to destination for matfill
    10238	No-assign-from source for matfill
    10239	Non-matrix argument for mattrace
    10240	Non-two-dimensional argument for mattrace
    10241	Non-square argument for mattrace
    10242	Bad epsilon for tan
    10243	Bad argument for tan
    10244	Bad epsilon for cot
    10245	Bad argument for cot
    10246	Bad epsilon for sec
    10247	Bad argument for sec
    10248	Bad epsilon for csc
    10249	Bad argument for csc
    10250	Bad epsilon for sinh
    10251	Bad argument for sinh
    10252	Bad epsilon for cosh
    10253	Bad argument for cosh
    10254	Bad epsilon for tanh
    10255	Bad argument for tanh
    10256	Bad epsilon for coth
    10257	Bad argument for coth
    10258	Bad epsilon for sech
    10259	Bad argument for sech
    10260	Bad epsilon for csch
    10261	Bad argument for csch
    10262	Bad epsilon for asin
    10263	Bad argument for asin
    10264	Bad epsilon for acos
    10265	Bad argument for acos
    10266	Bad epsilon for atan
    10267	Bad argument for atan
    10268	Bad epsilon for acot
    10269	Bad argument for acot
    10270	Bad epsilon for asec
    10271	Bad argument for asec
    10272	Bad epsilon for acsc
    10273	Bad argument for acsc
    10274	Bad epsilon for asin
    10275	Bad argument for asinh
    10276	Bad epsilon for acosh
    10277	Bad argument for acosh
    10278	Bad epsilon for atanh
    10279	Bad argument for atanh
    10280	Bad epsilon for acoth
    10281	Bad argument for acoth
    10282	Bad epsilon for asech
    10283	Bad argument for asech
    10284	Bad epsilon for acsch
    10285	Bad argument for acsch
    10286	Bad epsilon for gd
    10287	Bad argument for gd
    10288	Bad epsilon for agd
    10289	Bad argument for agd
    10290	Log of zero or infinity
    10291	String addition failure
    10292	String multiplication failure
    10293	String reversal failure
    10294	String subtraction failure
    10295	Bad argument type for bit
    10296	Index too large for bit
    10297	Non-integer second argument for setbit
    10298	Out-of-range index for setbit
    10299	Non-string first argument for setbit
    10300	Bad argument for or
    10301	Bad argument for and
    10302	Allocation failure for string or
    10303	Allocation failure for string and
    10304	Bad argument for xorvalue
    10305	Bad argument for comp
    10306	Allocation failure for string diff
    10307	Allocation failure for string comp
    10308	Bad first argument for segment
    10309	Bad second argument for segment
    10310	Bad third argument for segment
    10311	Failure for string segment
    10312	Bad argument type for highbit
    10313	Non-integer argument for highbit
    10314	Bad argument type for lowbit
    10315	Non-integer argument for lowbit
    10316	Bad argument type for unary hash op
    10317	Bad argument type for binary hash op
    10318	Bad first argument for head
    10319	Bad second argument for head
    10320	Failure for strhead
    10321	Bad first argument for tail
    10322	Bad second argument for tail
    10323	Failure for strtail
    10324	Failure for strshift
    10325	Non-string argument for strcmp
    10326	Bad argument type for strncmp
    10327	Varying types of argument for xor
    10328	Bad argument type for xor
    10329	Bad argument type for strcpy
    10330	Bad argument type for strncpy
    10331	Bad argument type for unary backslash
    10332	Bad argument type for setminus
    10333	Bad first argument type for indices
    10334	Bad second argument for indices
    10335	Too-large re(argument) for exp
    10336	Too-large re(argument) for sinh
    10337	Too-large re(argument) for cosh
    10338	Too-large im(argument) for sin
    10339	Too-large im(argument) for cos
    10340	Infinite or too-large result for gd
    10341	Infinite or too-large result for agd
    10342	Too-large value for power
    10343	Too-large value for root
    10344	Non-real first arg for digit
    10345	Non-integral second arg for digit
    10346	Bad third arg for digit
    10347	Bad first argument for places
    10348	Bad second argument for places
    10349	Bad first argument for digits
    10350	Bad second argument for digits
    10351	Bad first argument for ilog
    10352	Bad second argument for ilog
    10353	Bad argument for ilog10
    10354	Bad argument for ilog2
    10355	Non-integer second arg for comb
    10356	Too-large second arg for comb
    10357	Bad argument for catalan
    10358	Bad argument for bern
    10359	Bad argument for euler
    10360	Bad argument for sleep
    10361	calc_tty failure
    20000	base of user defined errors

*************
* 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.

    The builtin 'errno' can be use to convert an errno number into
    a slightly more meaningful error message:

	    badfile = fopen("not_a_file", "r");
	    if (!isfile(badfile)) {
		print "error #" : badfile : ":", errno(badfile);
	    }

    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 functions 'fputc' and 'fputs' write a character and string to
    a file respectively.

    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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: file,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/file,v $
##
## Under source code control:	1991/07/21 04:37:19
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: history,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/history,v $
##
## Under source code control:	1991/07/21 04:37:20
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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 specified by an
    ABORT opcode as described below.  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 attempt to allocate
    memory for the result of an integer arithmetic operation; this
    level may be appropriate for stopping a builtin operation like
    inversion of a large matrix.

    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.

ABORT opcodes

    If config("trace") & 2 is zero, ABORT opcodes are introduced at
    various places in the opcodes for evaluation of command lines
    and functions defined by "define ... { ... }" commands.  In the
    following, config("trace") has been set equal to 8 so that opcodes
    are displayed when a function is defined.   The function f(x)
    evaluates x + (x - 1) + (x - 2) + ... until a zero term is
    encountered.  If f() is called with a negative or fractional x,
    the calculation is never completed and to stop it, an interruption
    (on many systems, by ctrl-C) will be necessary.

	> config("trace", 8),
	> define f(x) {local s; while (x) {s += x--} return s}
	0: DEBUG line 2
	2: PARAMADDR x
	4: JUMPZ 19
	6: DEBUG line 2
	8: LOCALADDR s
	10: DUPLICATE
	11: PARAMADDR x
	13: POSTDEC
	14: POP
	15: ADD
	16: ASSIGNPOP
	17: JUMP 2
	19: DEBUG line 2
	21: LOCALADDR s
	23: RETURN
	f(x) defined

    (The line number following DEBUG refers to the line in the file
    from which the definition is read.)   If an attempt is made to
    evaluate f(-1), the effect of the DEBUG at opcode 6 ensures that
    a single SIGINT will stop the calculation at a start of
    {s += x--} loop.  In interactive mode, with ^C indicating
    input of ctrl-C, the displayed output is as in:

	> f(-1)
	^C
	[Abort level 1]
	"f": line 2: Calculation aborted at statement boundary

    The DEBUG opcodes are disabled by nonzero config("trace") & 2.
    Changing config("trace") to achieve this, and defining g(x) with
    the same definition as for f(x) gives:

	> define g(x) {local s; while (x) {s += x--} return s}
	0: PARAMADDR x
	2: JUMPZ 15
	4: LOCALADDR s
	6: DUPLICATE
	7: PARAMADDR x
	9: POSTDEC
	10: POP
	11: ADD
	12: ASSIGNPOP
	13: JUMP 0
	15: LOCALADDR s
	17: RETURN
	g(x) defined

    If g(-1) is called, two interrupts are necessary, as in:

	> g(-1)
	^C
	[Abort level 1]
	^C
	[Abort level 2]
	"g": Calculation aborted in opcode

## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.4 $
## @(#) $Id: interrupt,v 29.4 2000/07/17 15:38:52 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/interrupt,v $
##
## Under source code control:	1991/07/21 04:37:21
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* list
*************

NAME
    list - create list of specified values

SYNOPSIS
    list([x, [x, ... ]])

TYPES
    x		any, &any

    return	list

DESCRIPTION
    This function returns a list that is composed of the arguments x.
    If no args are given, an empty list is returned.

    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.

EXAMPLE
    > list(2,"three",4i)

    list (3 elements, 3 nonzero):
      [[0]] = 2
      [[1]] = "three"
      [[2]] = 4i

    > list()
	    list (0 elements, 0 nonzero)

LIMITS
    none

LINK LIBRARY
    none

SEE ALSO
    append, delete, insert, islist, pop, push, remove, rsearch, search, size

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: list,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/list,v $
##
## Under source code control:	1994/03/19 03:13:19
## File existed as early as:	1994
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* mat
*************

NAME
   mat - keyword to create a matrix value

SYNOPSIS
   mat [index-range-list] [ = {value_0. ...} ]
   mat [] [= {value_0, ...}]
   mat variable_1 ... [index-range-list] [ = {value_0, ...} ]
   mat variable_1 ... [] [ = {value_0, ...} ]

   mat [index-range-list_1[index-ranges-list_2] ... [ = { { ...} ...}  ]

   decl id_1 id_2 ... [index-range-list] ...

TYPES
   index-range-list	range_1 [, range_2, ...]  up to 4 ranges
   range_1, ...		integer, or integer_1 : integer_2
   value, value_1, ...	any
   variable_1 ...	lvalue
   decl			declarator = global, static or local
   id_1, ...		identifier

DESCRIPTION
   The expression  mat [index-range-list]  returns a matrix value.
   This may be assigned to one or more lvalues A, B, ... by either

	mat A B ... [index-range-list]

   or

	A = B = ... = mat[index-range-list]

   If a variable is specified by an expression that is not a symbol with
   possibly object element specifiers, the expression should be enclosed
   in parentheses.  For example, parentheses are required in
   mat (A[2]) [3]  and	mat (*p) [3]  but  mat P.x [3] is acceptable.

   When an index-range is specified as integer_1 : integer_2, where
   integer_1 and integer_2 are expressions which evaluate to integers,
   the index-range consists of all integers from the minimum of the
   two integers to the maximum of the two integers.  For example,
   mat[2:5, 0:4] and mat[5:2, 4:0] return the same matrix value.

   If an index-range is an expression which evaluates to an integer,
   the range is as if specified by 0 : integer - 1.  For example,
   mat[4] and mat[0:3] return the same 4-element matrix; mat[-2] and
   mat[-3:0] return the same 4-element matrix.

   If the variable A has a matrix value, then for integer indices
   i_1, i_2, ..., equal in number to the number of ranges specified at
   its creation, and such that each index is in the corresponding range,
   the matrix element associated with those index list is given as an
   lvalue by the expressions A[i_1, i_2, ...].

   The elements of the matrix are stored internally as a linear array
   in which locations are arranged in order of increasing indices.
   For example, in order of location, the six element of A = mat [2,3]
   are

	A[0,0], A[0,1], A[0,2], A[1,0], A[1,,1], A[1,2].

   These elements may also be specified using the double-bracket operator
   with a single integer index as in A[[0]], A[[1]], ..., A[[5]].
   If p is assigned the value &A[0.0], the address of A[[i]] for 0 <= i < 6
   is p + i as long as A exists and a new value is not assigned to A.

   When a matrix is created, each element is initially assigned the
   value zero.	Other values may be assigned then or later using the
   "= {...}" assignment operation.  Thus

	A = {value_0, value_1, ...}

   assigns the values value_0, value_1, ... to the elements A[[0]],
   A[[1]], ...	Any blank "value" is passed over.  For example,

	A = {1, , 2}

   will assign the value 1 to A[[0]], 2 to A[[2]] and leave all other
   elements unchanged.	Values may also be assigned to elements by
   simple assignments, as in A[0,0] = 1, A[0,2] = 2;

   If the index-range is left blank but an initializer list is specified
   as in

	mat A[] = {1, 2 }
	B = mat[] = {1, , 3, }

   the matrix created is one-dimensional.  If the list contains a
   positive number n of values or blanks, the result is as if the
   range were specified by [n], i.e. the range of indices is from
   0 to n - 1.	In the above examples, A is of size 2 with A[0] = 1
   and A[1] = 2;  B is of size 4 with B[0] = 1, B[1] = B[3] = 0,
   B[2] = 3.  The specification mat[] = { } creates the same as mat[1].

   If the index-range is left blank and no initializer list is specified,
   as in  mat C[]  or  C = mat[], the matrix assigned to C has zero
   dimension; this has one element C[].	 To assign a value using "= { ...}"
   at the same time as creating C, parentheses are required as in
   (mat[]) = {value}  or  (mat C[]) = {value}.	Later a value may be
   assigned to C[] by  C[] = value  or	C = {value}.

   The value assigned at any time to any element of a matrix can be of
   any type - number, string, list, matrix, object of previously specified
   type, etc.  For some matrix operations there are of course conditions
   that elements may have to satisfy: for example, addition of matrices
   requires that addition of corresponding elements be possible.
   If an element of a matrix is a structure for which indices or an
   object element specifier is required, an element of that structure is
   referred to by appropriate uses of [ ] or ., and so on if an element
   of that element is required.	 For example, one may have an expressions
   like

		A[1,2][3].alpha[2];

   if A[1,2][3].alpha is a list with at least three elements, A[1,2][3] is
   an object of a type like  obj {alpha, beta}, A[1,2] is a matrix of
   type mat[4] and A is a mat[2,3] matrix.  When an element of a matrix
   is a matrix and the total number of indices does not exceed 4, the
   indices can be combined into one list, e.g. the A[1,2][3] in the
   above example can be shortened to A[1,2,3].	(Unlike C, A[1,2] cannot
   be expressed as A[1][2].)

   The function ismat(V) returns 1 if V is a matrix, 0 otherwise.

   isident(V) returns 1 if V is a square matrix with diagonal elements 1,
   off-diagonal elements zero, or a zero- or one-dimensional matrix with
   every element 1; otherwise zero is returned.	 Thus  isident(V) = 1
   indicates that for  V * A  and  A * V  where A is any matrix of
   for which either product is defined and the elements of A are real
   or complex numbers, that product will equal A.

   If V is matrix-valued, test(V) returns 0 if every element of V tests
   as zero; otherwise 1 is returned.

   The dimension of a matrix A, i.e. the number of index-ranges in the
   initial creation of the matrix, is returned by the function matdim(A).
   For 1 <= i <= matdim(A), the minimum and maximum values for the i-th
   index range are returned by matmin(A, i) and matmax(A,i), respectively.
   The total number of elements in the matrix is returned by size(A).
   The sum of the elements in the matrix is returned by matsum(A).

   The default method of printing matrices is to give a line of information
   about the matrix, and to list on separate lines up to 15 elements,
   the indices and either the value (for numbers, strings, objects) or
   some descriptive information for lists or matrices, etc.
   Numbers are displayed in the current number-printing mode.
   The maximum number of elements to be printed can be assigned
   any nonnegative integer value m by config("maxprint", m).

   Users may define another method of printing matrices by defining a
   function mat_print(M); for example, for a not too big 2-dimensional
   matrix A it is a common practice to use a loop like:

		for (i = matmin(A,1); i <= matmax(A,1); i++) {
			for (j = matmin(A,2); j <= matmax(A,2); j++)
				printf("%8d", A[i,j];
			print;
		}

   The default printing may be restored by

		undefine mat_print;


   The keyword "mat" followed by two or more index-range-lists returns a
   matrix with indices specified by the first list, whose elements are
   matrices as determined by the later index-range-lists.  For
   example  mat[2][3]  is a 2-element matrix, each of whose elements has
   as its value a 3-element matrix.  Values may be assigned to the
   elements of the innermost matrices by nested	 = {...} operations as in

		mat [2][3] = {{1,2,3},{4,5,6}}

   An example of the use of mat with a declarator is

		global mat A B [2,3], C [4]

   This creates, if they do not already exist, three global variables with
   names A, B, C, and assigns to A and B the value mat[2,3] and to C mat[4].

   Some operations are defined for matrices.

   A == B
	Returns 1 if A and B are of the same "shape" and "corresponding"
	elements are equal; otherwise 0 is returned.  Being of the same
	shape means they have the same dimension d, and for each i <= d,

	    matmax(A,i) - matmin(A,i) == matmax(B,i) - matmin(B,i),

	One consequence of being the same shape is that the matrices will
	have the same size.   Elements "correspond" if they have the same
	double-bracket indices; thus A == B implies that A[[i]] == B[[i]]
	for 0 <= i < size(A) == size(B).

   A + B
   A - B
	These are defined A and B have the same shape, the element
	with double-bracket index j being evaluated by A[[j]] + B[[j]] and
	A[[j]] - B[[j]], respectively.	The index-ranges for the results
	are those for the matrix A.

   A[i,j]
	If A is two-dimensional, it is customary to speak of the indices
	i, j in A[i,j] as referring to rows and columns;  the number of
	rows is matmax(A,1) - matmin(A,1) + 1; the number of columns if
	matmax(A,2) - matmin(A,2) + 1.	A matrix is said to be square
	if it is two-dimensional and the number of rows is equal to the
	number of columns.

   A * B
	Multiplication is defined provided certain conditions by the
	dimensions and shapes of A and B are satisfied.	 If both have
	dimension 2 and the column-index-list for A is the same as
	the row-index-list for B, C = A * B is defined in the usual
	way so that for i in the row-index-list of A and j in the
	column-index-list for B,

		C[i,j] =  Sum A[i,k] * B[k,j]

	the sum being over k in the column-index-list of A.  The same
	formula is used so long as the number of columns in A is the same
	as the number of rows in B and k is taken to refer to the offset
	from matmin(A,2) and matmin(B,1), respectively, for A and B.
	If the multiplications and additions required cannot be performed,
	an execution error may occur or the result for C may contain
	one or more error-values as elements.

	If A or B has dimension zero, the result for A * B is simply
	that of multiplying the elements of the other matrix on the
	left by A[] or on the right by B[].

	If both A and B have dimension 1, A * B is defined if A and B
	have the same size; the result has the same index-list as A
	and each element is the product of corresponding elements of
	A and B.  If A and B have the same index-list, this multiplication
	is consistent with multiplication of 2D matrices if A and B are
	taken to represent 2D matrices for which the off-diagonal elements
	are zero and the diagonal elements are those of A and B.
	the real and complex numbers.

	If A is of dimension 1 and B is of dimension 2, A * B is defined
	if the number of rows in B is the same as the size of A.  The
	result has the same index-lists as B; each row of B is multiplied
	on the left by the corresponding element of A.

	If A is of dimension 2 and B is of dimension 1, A * B is defined
	if number of columns in A is the same as the size of A.	 The
	result has the same index-lists as A; each column of A is
	multiplied on the right by the corresponding element of B.

	The algebra of additions and multiplications involving both one-
	and two-dimensional matrices is particularly simple when all the
	elements are real or complex numbers and all the index-lists are
	the same, as occurs, for example, if for some positive integer n,
	all the matrices start as  mat [n]  or	mat [n,n].

    det(A)
	If A is a square, det(A) is evaluated by an algorithm that returns
	the determinant of A if the elements of A are real or complex
	numbers, and if such an A is non-singular, inverse(A) returns
	the inverse of A indexed in the same way as A.	For matrix A of
	dimension 0 or 1, det(A) is defined as the product of the elements
	of A in the order in which they occur in A, inverse(A) returns
	a matrix indexed in the same way as A with each element inverted.


   The following functions are defined to return matrices with the same
	index-ranges as A and the specified operations performed on all
	elements of A.	Here num is an arbitrary complex number (nonzero
	when it is a divisor), int an integer, rnd a rounding-type
	specifier integer, real a real number.

		num * A
		A * num
		A / num
		- A
		conj(A)
		A << int, A >> int
		scale(A, int)
		round(A, int, rnd)
		bround(A, int, rnd)
		appr(A, real, rnd)
		int(A)
		frac(A)
		A // real
		A % real
		A ^ int

   If A and B are one-dimensional of the same size dp(A, B) returns
	their dot-product, i.e. the sum of the products of corresponding
	elements.

   If A and B are one-dimension and of size 3, cp(A, B) returns their
	cross-product.

   randperm(A) returns a matrix indexed the same as A in which the elements
	of A have been randomly permuted.

   sort(A) returns a matrix indexed the same as A in which the elements
	of A have been sorted.

   If A is an lvalue whose current value is a matrix, matfill(A, v)
	assigns the value v to every element of A, and if also, A is
	square, matfill(A, v1, v2) assigns v1 to the off-diagonal elements,
	v2 to the diagonal elements.  To create and assign to A the unit
	n * n matrix, one may use matfill(mat A[n,n], 0, 1).

   For a square matrix A, mattrace(A) returns the trace of A, i.e. the
	sum of the diagonal elements.  For zero- or one-dimensional A,
	mattrace(A) returns the sum of the elements of A.

   For a two-dimensional matrix A, mattrans(A) returns the transpose
	of A, i.e. if A is mat[m,n], it returns a mat[n,m] matrix with
	[i,j] element equal to A[j,i].	For zero- or one-dimensional A,
	mattrace(A) returns a matrix with the same value as A.

   The functions search(A, value, start, end]) and
   rsearch(A, value, start, end]) return the first or last index i
   for which A[[i]] == value and start <= i < end, or if there is
   no such index, the null value.   For further information on default
   values and the use of an "accept" function, see the help files for
   search and rsearch.

   reverse(A) returns a matrix with the same index-lists as A but the
   elements in reversed order.

   The copy and blkcpy functions may be used to copy data to a matrix from
   a matrix or list, or from a matrix to a list.  In copying from a
   matrix to a matrix the matrices need not have the same dimension;
   in effect they are treated as linear arrays.

EXAMPLE
	> obj point {x,y}
	> mat A[5] = {1, 2+3i, "ab", mat[2] = {4,5}. obj point = {6,7}}
	> A
	mat [5] (5 elements, 5 nonzero):
	  [0] = 1
	  [1] = 2+3i
	  [2] = "ab"
	  [3] = mat [2] (2 elements, 2 nonzero)
	  [4] = obj point {6, 7}

	> print A[0], A[1], A[2], A[3][0], A[4].x
	1 2+3i ab 4 6

	> define point_add(a,b) = obj point = {a.x + b.x, a.y + b.y}
	point_add(a,b) defined

	> mat [B] = {8, , "cd", mat[2] = {9,10}, obj point = {11,12}}
	> A + B

	mat [5] (5 elements, 5 nonzero):
	  [0] = 9
	  [1] = 2+3i
	  [2] = "abcd"
	  [3] = mat [2] (2 elements, 2 nonzero)
	  [4] = obj point {17, 19}

	> mat C[2,2] = {1,2,3,4}
	> C^10

	mat [2,2] (4 elements, 4 nonzero):
	  [0,0] = 4783807
	  [0,1] = 6972050
	  [1,0] = 10458075
	  [1,1] = 15241882

	> C^-10

	mat [2,2] (4 elements, 4 nonzero):
	  [0,0] = 14884.650390625
	  [0,1] = -6808.642578125
	  [1,0] = -10212.9638671875
	  [1,1] = 4671.6865234375

	> mat A[4] = {1,2,3,4}, A * reverse(A);

	mat [4] (4 elements, 4 nonzero):
	  [0] = 4
	  [1] = 6
	  [2] = 6
	  [3] = 4

LIMITS
   The theoretical upper bound for the absolute values of indices is
   2^31 - 1, but the size of matrices that can be handled in practice will
   be limited by the availability of memory and what is an acceptable
   runtime.  For example, although it may take only a fraction of a
   second to invert a 10 * 10 matrix, it will probably take about 1000
   times as long to invert a 100 * 100 matrix.

LINK LIBRARY
   n/a

SEE ALSO
   ismat, matdim, matmax, matmin, mattrans, mattrace, matsum, det, inverse,
   isident, test, config, search, rsearch, reverse, copy, blkcpy, dp, cp,
   randperm, sort

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: mat,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/mat,v $
##
## Under source code control:	1991/07/21 04:37:22
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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
	    xx_or	2	boolean or
	    xx_and	2	boolean and
	    xx_not	1	boolean not
	    xx_fact	1	factorial


    Also see the standard resource files:

	    dms.cal
	    mod.cal
	    poly.cal
	    quat.cal
	    surd.cal

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: obj.file,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/obj.file,v $
##
## Under source code control:	1991/07/21 04:37:22
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* operator
*************

operators

    The operators are similar to C, but there are some differences in
    the associativity and precedence rules for some operators.	In
    addition, there are several operators not in C, and some C
    operators are missing.  A more detailed discussion of situations
    that may be unexpected for the C programmer may be found in
    the 'unexpected' help file.

    Below is a list giving the operators arranged in order of
    precedence, from the least tightly binding to the most tightly
    binding.  Except where otherwise indicated, operators at the same
    level of precedence associate from left to right.

    Unlike C, calc has a definite order for evaluation of terms (addends
    in a sum, factors in a product, arguments for a function or a
    matrix, etc.).  This order is always from left to right. but
    skipping of terms may occur for ||, && and ? : .  For example,
    an expression of the form:

	    A * B + C * D

    is evaluated in the following order:

	    A
	    B
	    A * B
	    C
	    D
	    C * D
	    A * B + C * D

    This order of evaluation is significant if evaluation of a
    term changes a variable on which a later term depends.  For example:

	    x++ * x++ + x++ * x++

    returns the value of:

	    x * (x + 1) + (x + 2) * (x + 3)

    and increments x as if by x += 4.  Similarly, for functions f, g,
    the expression:

	    f(x++, x++) + g(x++)

    evaluates to:

	    f(x, x + 1) + g(x + 2)

    and increments x three times.

    In A || B, B is read only if A tests as false;  in A && B, B is
    read only if A tests as true.  Thus if x is nonzero,
    x++ || x++ returns x and increments x once; if x is zero,
    it returns x + 1 and increments x twice.


    ,	Comma operator.
	    a, b returns the value of b.
	    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 expression.
	    E.g., if A is a matrix, A[(a, b), c] evaluates a, b, and c, and
	    returns the value of A[b, c].

    +=	-=  *=	/=  %=	//=  &=	 |=  <<=  >>=  ^=  **=
	 Operator-with-assignments.
	    These associate from left to right, e.g. a += b *= c has the
	    effect of a = (a + b) * c, where only a is required to be an
	    lvalue.  For the effect of b *= c; a += b; when both a and b
	    are lvalues, use a += (b *= c).

    =	Assignment.
	    As in C, this, when repeated, this associates from right to left,
	    e.g. a = b = c has the effect of a = (b = c).  Here both a and b
	    are to be lvalues.

    ? : Conditional value.
	    a ? b : c  returns b if a tests as true (i.e. nonzero if
	    a is a number), 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-true?" test is meaningful for a.
	    As in C, this operator associates from right to left,
	    i.e. a ? b : c ? d : e is evaluated as a ? b : (c ? d : e).

    ||	Logical OR.
	    Unlike C, the result for a || b is one of the operands
	    a, b rather than one of the numbers 0 and 1.
	    a || b is equivalent to a ? a : b, i.e. if a tests as
	    true, a is returned, otherwise b.  The effect in a
	    test like "if (a || b) ... " is the same as in C.

    &&	Logical AND.
	    Unlike C, the result for a && b is one of the operands
	    a, b rather than one of the numbers 0 and 1.
	    a && b is equivalent to a ? b : a, i.e. if a tests as
	    true, b is returned, otherwise a.  The effect in a
	    test like "if (a && b) ... " is the same as in C.

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

    +  -
	    Binary plus and minus and unary plus and minus when applied to
	    a first or only term.

    *  /  //  %
	    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).

    +  -  !
	    Plus (+) and minus (-) have their usual meanings as unary
	    prefix operators at this level of precedence when applied to
	    other than a first or only term.

	    As a prefix operator, '!' is the logical NOT: !a returns 0 if
	    a tests as nonzero, and 1 if a tests as 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.

	    As a postfix operator ! gives the factorial function, i.e.
	    a! = fact(a).

    ++	--
	    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.


    See the 'unexpected' help file for a list of unexpected
    surprises in calc syntax/usage.  Persons familiar with C should
    read the 'unexpected' help file to avoid confusion.

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: operator,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/operator,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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.


    Also see the help topic:

	    command	    top level commands
	    expression	    calc expression syntax
	    builtin	    calc builtin functions
	    usage	    how to invoke the calc command and calc -options

## Copyright (C) 1999  Landon Curt Noll
##
## Calc is open software; you can redistribute it and/or modify it under
## the terms of the version 2.1 of the GNU Lesser General Public License
## as published by the Free Software Foundation.
##
## Calc is distributed in the hope that it will be useful, but WITHOUT
## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
## Public License for more details.
##
## A copy of version 2.1 of the GNU Lesser General Public License is
## distributed with calc under the filename COPYING-LGPL.  You should have
## received a copy with calc; if not, write to Free Software Foundation, Inc.
## 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
##
## @(#) $Revision: 29.2 $
## @(#) $Id: statement,v 29.2 2000/06/07 14:02:33 chongo Exp $
## @(#) $Source: /usr/local/src/cmd/calc/help/RCS/statement,v $
##
## Under source code control:	1991/07/21 04:37:23
## File existed as early as:	1991
##
## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/

*************
* resource
*************

Calc standard resource files
----------------------------

To load a resource file, try:

    read filename

You do not need to add the .cal extension to the filename.  Calc
will search along the $CALCPATH (see ``help environment'').

Normally a resource file will simply define some functions.  By default,
most resource files will print out a short message when they are read.
For example:

    > read lucas
    lucas(h,n) defined
    gen_u0(h,n,v1) defined
    gen_v1(h,n) defined
    ldebug(funct,str) defined

will cause calc to load and execute the 'lucas.cal' resource file.
Executing the resource file will cause several functions to be defined.
Executing the lucas function:

    > lucas(149,60)
	    1
    > lucas(146,61)
	    0

shows that 149*2^60-1 is prime whereas 146*2^61-1 is not.

=-=

Calc resource file files are provided because they serve as examples of
how use the calc language, and/or because the authors thought them to
be useful!

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

    calc-contrib at asthe dot com

    [[ NOTE: Replace 'at' with @, 'dot' is with . and remove the spaces ]]
    [[ NOTE: The EMail address uses 'asthe' and the web site URL uses 'isthe' ]]

By convention, a resource file only defines and/or initializes functions,
objects and variables.	(The regress.cal and testxxx.cal regression test
suite is an exception.)	 Also by convention, an additional usage message
regarding important object and functions is printed.

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

    /* pull in needed resource files */
    read -once "surd"
    read -once "lucas"

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

The "resource_debug" parameter is intended for controlling the possible
display of special information relating to functions, objects, and
other structures created by instructions in calc resource files.
Zero value of config("resource_debug") means that no such information
is displayed.  For other values, the non-zero bits which currently
have meanings are as follows:

    n		Meaning of bit n of config("resource_debug")

    0	When a function is defined, redefined or undefined at
	interactive level, a message saying what has been done
	is displayed.

    1	When a function is defined, redefined or undefined during
	the reading of a file, a message saying what has been done
	is displayed.

    2	Show func will display more information about a functions
	arguments as well as more argument sdummary information.

    3	During execution, allow calc standard resource files
	to output additional debugging information.

The value for config("resource_debug") in both oldstd and newstd is 3,
but if calc is invoked with the -d flag, its initial value is zero.
Thus, if calc is started without the -d flag, until config("resource_debug")
is changed, a message will be output when a function is defined
either interactively or during the reading of a file.

Sometimes the information printed is not enough.  In addition to the
standard information, one might want to print:

	* useful obj definitions
	* functions with optional args
	* functions with optional args where the param() interface is used

For these cases we suggest that you place at the bottom of your code
something that prints extra information if config("resource_debug") has
either of the bottom 2 bits set:

	if (config("resource_debug") & 3) {
		print "obj xyz defined";
		print "funcA([val1 [, val2]]) defined";
		print "funcB(size, mass, ...) defined";
	}

If your the resource file needs to output special debugging informatin,
we recommend that you check for bit 3 of the config("resource_debug")
before printing the debug statement:

	if (config("resource_debug") & 8) {
		print "DEBUG: This a sample debug statement";
	}

=-=

The following is a brief description of some of the calc resource files
that are shipped with calc.  See above for example of how to read in
and execute these files.

beer.cal

    Calc's contribution to the 99 Bottles of Beer web page:

	http://www.ionet.net/~timtroyr/funhouse/beer.html#calc


bernoulli.cal

    B(n)

    Calculate the nth Bernoulli number.

    NOTE: There is now a bernoulli() builtin function.  This file is
    	  left here for backward compatibility and now simply returns
	  the buildin function.


bigprime.cal

    bigprime(a, m, p)

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


chi.cal

    Z(x[, eps])
    P(x[, eps])
    chi_prob(chi_sq, v[, eps])

    Computes the Probability, given the Null Hypothesis, that a given
    Chi squared values >= chi_sq with v degrees of freedom.

    The chi_prob() function does not work well with odd degrees of freedom.
    It is reasonable with even degrees of freedom, although one must give
    a sifficently small error term as the degress gets large (>100).

    The Z(x) and P(x) are internal statistical funcions.

    eps is an optional epsilon() like error term.


chrem.cal

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

    Chinese remainder theorem/problem solver.


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

    efactor(iN, ia, B, force)

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


hello.cal

    Calc's contribution to the Hello World! page:

	http://www.latech.edu/~acm/HelloWorld.s 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).


    C-like statements
    -----------------
    { statement }
    { statement; ... statement }
    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.

	    See 'help expression' for details on expressions.
	    See 'help builtin' for details on calc builtin functions.


    return
    ------
    return optionalexpr
    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
    ------
    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.


    matrix
    ------
    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");


    object
    ------
    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;


    print expressions
    -----------------
    print expr
    print expr, ... expr
    print expr: ... expr
	    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 