next up previous contents index
Next: How to use additional Up: Additional expression evaluators Previous: The expression evaluator using   Contents   Index


How to define new expression evaluators

Here is the part of the file interp.h that corresponds to additional expression evaluators :

typedef void  (*oper2_expr)(void *, void *, void *);
typedef void  (*oper1_expr)(void *);
typedef int   (*oper0_expr)(void *);
typedef void  (*oper3_expr)(void *, char *);
typedef void  (*oper4_expr)(void **);
typedef char* (*oper5_expr)(void *);
typedef void* (*oper6_expr)(void *);
typedef void* (*oper)(char *);

typedef struct
{
    oper1_expr    clear;
    oper1_expr    Zero;
    oper1_expr    neg;
    oper0_expr    iszero;
    oper2_expr    add;
    oper2_expr    sub;
    oper2_expr    mul;
    oper2_expr    pow;
    oper2_expr    div;
    oper3_expr    set;
    oper4_expr    Init;
    oper5_expr    print;
    oper6_expr    copy;
    oper0_expr    sign;
    int           n_oper;
    char        **oper_name;
    oper         *OPER;
    int           n_var;
    char         *desc;
} EXPREVAL_GEN;

EXPREVAL_GEN   *Expreval_ops;

typedef struct {
    char *name;
    void **value;
} Vars_Gen;

Vars_Gen  **VArs_global_Gen;
int        *_NBFONC_Gen;
typedef struct
{
   char*        name;                     /* Function name                 */
   int          args;                     /* Number of arguments to expect */
   void         (*func)(void**, void**);  /* Pointer to function           */
} FUNCTIONGen;
extern FUNCTIONGen *Funcs_Gen[];
int             NB_expr_eval;          /* Number of supplementary 
                                          evaluators */

Here it is assumed that the numbers we work with are represented by pointers to void. These pointers should actually contain the addresses of the numbers.

The directory expr_evals contains the definition of several expression evaluators. To each expression evaluator corresponds a main file in the test/extra directory that produces a test program for the interpcom library where this new expression evaluator can be used. The file main_all of the test/extra directory produces a test program where all the expression evaluators can be used. The expression evaluators in the expr_evals directory are :

-
_dummy.c : an expression evaluator that uses double precision numbers. It should work just like the ordinary expression evaluator, perhaps more slowly. The reader should look at this file to see how an expression evaluator is implemented.
-
_mapm.c : an expression evaluator that uses the library mapm (Mike's Arbitrary Precision Math Library) by Michael C. Ring This library can be found at
http://tc.umn.edu/~ringx004. The default precision used here is 50 digits. It is stored in the integer _mapm_dec_places (see the file main_mapm.c in the test directory). It would be possible to create a new command to change this default precision.
-
_GMP.c : an expression evaluator that uses the gmp library (that can be found at many places, beeing a part of the GNU project). More precisely this expression evaluator uses rational numbers, i.e. quotients of arbitrary big integers. In this expression evaluator some operations will produce nothing (i.e. give a zero result) : pow, sqrt.
-
_matrix.c : an expression evaluator that uses 2X2 matrices. It comes with the command set_mat that is used to set the values of a matrix. Example :
- interpcom -> a=1
[1.0000000000000000,0.0000000000000000,0.0000000000000000,1.0000000000000000]
- interpcom -> set_mat a 1 -2.5 4 2.1
- interpcom -> a
[1.0000000000000000,-2.5000000000000000,4.0000000000000000,2.1000000000000001]
Here also the functions pow and sqrt are not implemented.


Now we will indicate how new expression evaluators should be implemented. First of all an EXPREVAL_GEN structure must be created, with the appropriate functions that are listed below. The "numbers" that are used in the new expression evaluator must be represented by pointers to void.


Member clear : this number destroys the number represented in its argument, i.e. it frees the memory used to define this number.

Member Zero : this functions gives the value 0 to the number represented by its argument.

Member neg : this function negates the number represented by its argument.

Member iszero : this function returns 1 if its argument is the number 0, and 1 otherwise.

Member add : this function adds the two numbers represented by the two last arguments, and puts the result in the number represented by the first argument.

Member sub : this function substracts the two numbers represented by the two last arguments, and puts the result in the number represented by the first argument.

Member mul : this function multiplies the two numbers represented by the two last arguments, and puts the result in the number represented by the first argument.

Member pow : this function computes the power of the number represented by the second argument to the number represented by the third argument, and puts the result in the number represented by the first argument.

Member div : this function divides the two numbers represented by the two last arguments, and puts the result in the number represented by the first argument.

Member set : this function gives the value represented by the second argument to the number represented by the first argument.

Member Init : if the argument is void **s, this function creates a new number a puts its address in s[0].

Member print : this function returns a character string representing the number corresponding to its first argument.

Member copy : this function returns the address of a new number having the same value as the number represented by the first argument.

Member sign : this function returns the the number having represented by the first argument (i.e. -1 if the number is negative, 0 if it is 0, and 1 if it is positive).

The members n_oper, oper_name, OPER and n_var are not yet used and should be respectively 0, NULL, NULL and 1.

The functions used by the new expression evaluator should be put in a FUNCTIONGen array (see _dummy.c). Each function F should be of type

void    func(void **res, void **x)

Here res is the address of the result (so the number computed by the function is represented by res[0]), and the other argument represent the array of arguments of F.

Now the function init_expr_GEN must be created to indicate which expression evaluators will be used, and the array Funcs_Gen must be defined and filled with the new corresponding function arrays. This can be done for instance in the main source file.

For instance, if two new expression evaluators are created, we could write the following :

FUNCTIONGen *Funcs_Gen[] = {
        Funcs_1,      /* array of functions for the first additional
	                 expression evaluator */
        Funcs_2,      /* array of functions for the second additional
	                 expression evaluator */
};

void init_expr_GEN(flow_data *flow_interp)
{
    NB_expr_eval = 4;
    _NBFONC_Gen[0] = _NBFONC_1;
    Expreval_ops[0] = _exprev_1;
    _NBFONC_Gen[1] = _NBFONC_2;
    Expreval_ops[1] = _exprev_2;
}

Here NB_expr_eval is the total number of expression evaluators (the two that are defined in the library plus the two supplementary ones). The EXPREVAL_GEN structure corresponding to the first new expression evaluator is _exprev_1, which is put in Expreval_ops[0], the number of corresponding functions (defined in Funcs_1) is _NBFONC_1, which is put in _NBFONC_Gen[0], and so on.

The function init_expr_GEN can also contain some initializations needed by the new expression evaluators (see the file main_all.c where three additional expression evaluators are defined).


next up previous contents index
Next: How to use additional Up: Additional expression evaluators Previous: The expression evaluator using   Contents   Index
2009-11-12