*******************************************************************************

                                   EVAL 1.00

                 EVAL is a mathematical expression evaluator.
  It is intended to be used from the DOS command line or inside a batch file
                    80 bits long double precision is used.

                Copyright (C) 1994 Juan M. Aguirregabiria 1994
                              All right reserved

       EVAL can be freely used and distributed, but you cannot sell it.

                            First version 12-31-93

                            Last revision  3-31-93

*******************************************************************************

Installing EVAL
===============
Put the program EVAL.EXE and help file EVAL.HLP in any directory of your PATH.

Using EVAL
==========
EVAL is called from the DOS command line in one of the following forms: 

 EVAL ?
   A help window will open.

 EVAL expression
   The expression will be evaluated and returned.

 EVAL
     The user will be prompted (>>) to enter expressions, which will be 
   evaluated and displayed. Using a line with a single ? will open the help 
   screen. 
     Enter a blank line (or <Ctrl Z> to end the session. 
     A line in the form "command or "command" will invoke the command in a DOS 
   shell. 
     A line in the form " or "" will start a DOS shell. 
     To exit EVAL enter a blank line or a <Ctrl Z> character.

 EVAL < filename The lines from filename will be read and (if they are not void 
   and do not start by ;) evaluated and returned. 

In any case the ouput of EVAL will be directed to the standard output device 
(stdout) and can be redirected to an output file appending to the command line 
> output, as usual. 

Expressions
===========
A line may contain one or several expression separated by ; or $. If $ is used 
the corresponding output will not be printed. If ; (or nothing) is used the 
result will be printed (unless printall(0) has been used; see below). 

Any character following a # will be ignored. This allows introducing comments 
in the line. 

Blank lines are ignored.

An expression is formed, in a very standard way, by the following items 
optionally separated by spaces: 

 - Assignments
 - Numbers: -2, 1E-12, -1.02e2, .2, etc.
 - Operators
 - Parenthesis to change precedence.
 - Predefined constants:
   degree = /180
   e = E = 2.71828...
    = pi = PI = Pi = pI = 3.14159...
   They are searched after parameters.
 - Mathematical Functions.
 - Control functions.
 - The last expression under the name last.
 - The last 10 expressions as ans[n]. The index n 
   is incremented with each expression evaluation.
 - Up to 10 user defined variables defined in 
   Assignments.

See also the BNF description of the expression compiler.



Assignments
===========
You can change the value of variables by using:
                 variable = value 
where 'value' is an arbitrary expression (even another assignment) and 
'variable' may be any predefined variable (last,ans[0],...,ans[9]) or any of 
the user defined variables. If the variable is not found it will be added to 
the user defined variables (up to a maximum of 10). The spaces around the '=' 
symbol are optional. 

The result of an assignment statement is 'value' and can be used in complex 
expressions, like the following ones: 
         a1 = a2 = 2
         a1 = (a2 = 3)*3

Operators
=========
 Mathematical operators:
 +        addition
 -        substraction or negation
 *        multiplication
 /        division
  = div  integer division: xy = [x/y]
 % = mod  remainder:        x%y = x/y-[x/y]
 ^ = pow  exponentiation:   x^2 = x*x

 Relational operators return 1/0 for TRUE/FALSE:
 <      less than
 <=     less or equal:    a <= b means a  b
 >      greater than
 >=     greater or equal: a >= b means a  b
 ==     equal to:         a == b means a = b
 !=     not equal to

 Logical operators return 1/0 for TRUE/FALSE:
 &&     and
 ||     or
 !      not
 (Only the operands necessary to establish the
 result are evaluated.)

 Conditional operator:
 c ? t : f  returns t if c != 0,
                    f if c == 0.
          It is equivalent to if(c,t,f)
 
 Operator precedence, from lowest to highest:
     1. ?:         (Conditional operator)
     2. ||
     3. &&
     4. == !=
     5. < <= > >=
     6. + -        (binary)
     7. * /  %
     8. ^
     9. ! + -      (unary)

Functions
=========
 Case is ignored.

 One-variable functions:
 abs   = fabs    abs(x) = x
 acos  = arccos  cos(acos(x)) = x
 asin  = arcsin  sin(asin(x)) = x
 atan  = arctan  tan(atan(x)) = x
                 Result in [-/2,/2].
 ceil            ceil(x) = -int(-x)
 cos             cosinus function
 cosh            hyperbolic cosinus
 erf             error function
 erfc            complementary error f.
 exp             exponential function
 floor = int     int(x) = E(x) = [x]
 fracc           fracc(x) = x-int(x)
 ln    = log     natural logarithm
 log10           decimal logarithm
 round           nearest integer
 sgn   = sign    sign function
 sin             sinus function
 sinh            hyperbolic sinus
 sqr             sqr(x) = x*x = x^2
 sqrt            sqrt(x) = x
 step            Heaviside function
                 (x) = 1, x > 0
                 (0) = 0.5
                 (x) = 0, x < 0
 tan             tangent function
 tanh            hyperbolic tangent

 Two-variable functions:
 arctan2 = atan2 atan2(y,x) = atan(y/x)
                 Result in (-,].
 div             div(x,y) = x  y
 hypot           hypot(x,y) = (x^2+y^2)
 mod             mod(x,y) = x % y
 pow             pow(x,y) = x^y
 random          random(x,y) = random number in 
                   (x,y). 
                   Use floor(random(a,b+1)) to 
                   select an integer from a to b. 
 
 Two multi-argument functions, max and min, which 
 return, respectively, the largest and smallest 
 of their arguments. 

 A special function, if, with two meanings:
 if(c,t,f)   returns t if c != 0,
                     f if c = 0.
 if(c,p,z,n) returns p if c > 0,
                     z if c = 0 and
                     n if c < 0.
 if(c,t,f) is equivalent to (c) ? t : f.
 Only 'c' and the returned argument, which can be
 a full expression, are evaluated. This function 
 can be seen as a simple control structure. 

Control functions
=================
 The following control functions set some 
 internal flags that control the output format: 
 
 precision(n) The ouput will use from 1 to n 
                digits. Use 0 < n < 16 for 
                sensible output. The default 
                value is 15.

 labels(n)    The labels ans[n] (which are
                disabled if EVAL expr has been 
                used) will be disabled/enabled
                if n equals/is different from 0.

 printall(n)  The printing of each result will be 
                disabled/enabled if n equals/is 
                different from 0. By default the 
                corresponding flag is enabled. 
                If the program terminates with it 
                disabled, the last value will be 
                printed.

 All these functions return the previous value of 
 the corresponding flag. Their action takes 
 place immediately.


BNF description of the expression compiler
==========================================
 expression ::= assignment | 
                assignment ? expression 
                           : expression
 assignment ::=  or-expression | variable = expression
 or-expression ::= and-expression
                   {|| and-expression}
 and-expression ::= equality {&& equality}
 equality ::= relation |
              relation equality-operator relation
 equality-operator ::= == | !=
 relation ::= addend |
              addend relational-operator addend
 relational-operator ::= < | > | <= | >=
 addend ::= term {adding-operator term}
 adding-operator ::= + | -
 term ::= signed-power-factor
          {multiplying-operator
           signed-power-factor}
 multiplying-operator ::= * | / |  | %
 signed-power-factor ::= power-factor      |
                         sign power-factor |
                         ! power-factor
 power-factor ::= factor | factor ^ signed-factor
 signed-factor ::= factor | sign factor
 factor ::= constant | variable | number
                     | function | ( expression )
 sign ::= + | -
 variable ::= identifier | identifier [ integer ]
 constant ::= identifier
 number ::=   digit {digit} . {digit} scale |
              digit {digit} . {digit}       |
              digit {digit}           scale |
              digit {digit}                 |
            . digit {digit}           scale |
            . digit {digit}
 function ::= identifier ( expression
                           {, expression } )
 identifier ::= letter {letter | digit}
 integer ::= digit {digit}
 letter ::= A | B | ... | Z | a | b | ... | z | _
 digit ::= 0 | 1 | ... | 9
 scale ::= E scale-factor | e scale-factor
 scale-factor ::= digit {digit} |
                  sign digit {digit}


Error list
==========
Most errors can be easily understood in the context they happen. You can find 
in the following error list some hints to avoid them. Errors marked with an 
asterisk should not happen. (If they do, notify the author, please.) 

The following error types may happen:
         Compiler errors
         Floating point errors
         Function errors
         Interpreter errors

Compiler errors
===============
 These errors are issued by the expression 
 compiler when an incorrect Expressions is 
 encountered. The most probable location of the 
 error is over the cursor.
 
 '[ expected' ans must be followed by [.
 ') expected' A parenthesis is unbalanced.
 '] expected' A bracket is unbalanced.
 ', expected' Another argument must be provided.
 'Extra character(s)' Some characters follow a 
         complete expression. Maybe you forgot a 
         parenthesis or an operator. 
 'Index out of bounds' Only ans[0] to ans[9] are 
         available.
 'Invalid character' The character cannot be used 
         in this context.
 'Invalid index' It must be a constant number.
 'P-code too long' Too complex expression.
 'Unexpected end of expression' Maybe an
         unbalanced parenthesis.
 'Unknown function' Undefined or misspelled 
         function. 
 'Unknown identifier' Undefined or misspelled
         variable. 

Floating point errors
=====================
 These errors may happen when evaluating 
 numerical expressions.

 'Denormal operand'  (*)
 'Division by 0'     1/0, etc.
 'Inexact operation' (*)
 'Invalid operation' 0/0, etc.
 'Overflow':         1e200*1e200, etc.
 'Underflow'         (*)

Function errors
=============== 
 They give the function where the error happened, 
 the value of the two arguments (even if the 
 function has a single argument, a second 
 meaningless value is given) and the type of 
 error. 
  
 'argument domain error'        log(-1), etc.
 'argument singularity'         0^-2, etc.
 'overflow range error'         e^1000, etc.
 'partial loss of significance' (*) 
 'total loss of significance'   sin(1e70), etc.
 'underflow range error'        (*) 

Interpreter errors
==================
 These errors may happen when evaluating the 
 code generated by the expression compiler.

 'Invalid code' (*)
 'Invalid stack' (*)
 'Stack overflow' An expression was too complex. 
 'Code for erf not converging' (*) 
