Expression evaluator


The expression evaluator is due to Mark Morley. Some modifications have been made, to add the possibility to evaluate objects. It is possible to use the 4 operators +,-, *, / and parentheses. One can also define and use variables, and use the usual mathematical functions.

Everything that is not recognized by the interpreter as a command or a program is supposed to be a numerical expression. It is computed and the result is printed on screen. For example

interpreter -> a=2
2.000000
interpreter -> b=3
3.000000
interpreter -> a+b
5.000000
interpreter -> cos(a)
-0.416147

It is possible to use numerical expressions as arguments of commands (or command files and programs) (cf. sections 6.4 and 3).
 


6.1 Variables


Variables are defined when they are assigned for the first time, except two predefined variables, e  and pi . If a numerical expression contains a non defined variable, the result is set to 0. Uppercase and lowercase characters are distinguished.

It is possible to know which variables are defined and their values by using the command  varlist .

Example :

interpreter -> varlist
a=2.000000
b=3.000000

It is possible to undefine variables by using the command undef.

Example :

interpreter -> undef  a
interpreter -> varlist
b=3.000000

The command interpreter uses hidden variables, essentially for the names of the dimensions of objects. A hidden variable is simply a variable whith a name whose first character is not printable. So it is not possible to access directly these variables. Inside a program one may use the functions  S_convert_int  or  S_convert_float . Their unique argument is a string of characters. These functions add a non printable character at the beginning of the string, send this new string to the expression evaluator and returns the evaluation of the string. For example

S_convert_float("sq_root_of_2=sqrt(2)");

will create the hidden variable  sq_root_of_2 (if it did not exist) and assign the square root of 2 to this variable. It is possible to define and fix hidden variables in the !var  section of the initialization file. With the command initvar  it is possible to use the values of hidden variables. This command will create (or modify) variables which have the same names as the hidden ones (except of course for the first character that is omitted) and give them the values of the corresponding hidden variables. Subsequent modifications of the visible variables will not affect the values of the hidden ones.

The maximal number of variables that can be defined is 500. It is fixed in the source file  interp.h :

#define MAXXVARS 500   /* Max user-defined variables */
 
 
 


6.2 Functions


The mathematical functions that the expression evaluator knows are in the array  Funcs[] (it is an array of structures  FUNCTION ). This array must be defined by the user.  The total number of functions is _NBFONC, which must be set by the user. An array of functions is predefined in the library, it is called  Funcs_interp, and the number of functions defined in  Funcs_interp  is contained is the integer  _NBFONC0.

FUNCTION Funcs_interp[] =
{
/* name, funtion to call */
    { "sin", 1, sin } ,             /* 0 */
    { "cos", 1, cos } ,           /* 1 */
    { "tan", 1, tan } ,            /* 2 */
    { "asin", 1, asin } ,         /* 3 */
    { "acos", 1, acos } ,       /* 4 */
    { "atan", 1, atan } ,        /* 5 */
    { "sinh", 1, sinh } ,         /* 6 */
    { "cosh", 1, cosh } ,       /* 7 */
    { "tanh", 1, tanh } ,        /* 8 */
    { "exp", 1, exp } ,          /* 9 */
    { "log", 1, log } ,            /* 10 */
    { "log10", 1, log10 } ,     /* 11 */
    { "sqrt", 1, sqrt } ,         /* 12 */
    { "floor", 1, floor } ,       /* 13 */
    { "ceil", 1, ceil } ,           /* 14 */
    { "abs", 1, fabs } ,         /* 15 */
    { "hypot", 2, hypot } ,    /* 16 */
    { "deg", 1, deg } ,           /* 17 */
    { "rad", 1, rad } ,            /* 18 */
    { 0 }                              /* 19 */
} ;

int _NBFONC0=19;

For example if the program uses only the predefined array of functions, the main source file would look as follows :

. . . . . . . . . .
FUNCTION   *Funcs;

int   main(int argc, char *argv[])
{
    Funcs  =  Funcs_interp;
    _NBFONC  =  _NBFONC0;
    . . . . . . .

The first member of the structure  FUNCTION is the string character that will be used to call the function. The second member is the number of parameters of the function. It must be 1 or 2. The third member is the name of the function. It must be a real function with one or two real arguments. In the preceeding example the usual mathematical functions are used. It is also possible to put other functions found in some libraries of special functions, like cephes for example, or defined by the user.
 
 
 
 


6.3 Objects


The expression evaluator can use the values of the objects defined by the user. This is explained in the end of section 5.3. For example if the object  xxx  is a 2-dimensional array of real numbers, &xxx(2,5)  will be the value of the term  [2][5]  of the array represented by   xxx . It is possible also to use expressions such as  &xxx(i,2*i+j) , or even something like  &xxx(cos(2*z)+&tt(i,k),exp(u)) . If the indices are incorrect, i.e if the integer parts of the indices are negative or bigger that the dimensions of the object, the value of the expression will be zero.

For a complex object,  zzz  for example, &zzz(2,5)  will be the real part of the value of the term  [2][5]  of the array represented by  zzz . Equivalently, on can use  &zzz(2,5).r , and &zzz(2,5).i will give the imaginary part.
 
 
 
 


6.4 Numerical expressions as arguments


The functions

int   convert_int(char *);
double   convert_float(char *);

of the library can be used to parse numeric arguments. For example if the command  Xcom3  corresponding to the function

int   Xcom3_cmd(int argc, char* argv[]);

needs an argument which is an integer, the function  Xcom3_cmd should contain something like

int   n;
n = convert_int(argv[1]);

The function  convert_int  will send the string of characters to the expression evaluator and return the integer part of the evaluation of this string. The function  convert_float can be used to evaluate real arguments. This allows instructions like

interpreter -> Xcom3   i+2

for example.


Main page
Chapters   1   2   3   4   5   6   7   8    9    10   11