EXPR(3)                      C Programmer's Manual                     EXPR(3)

       expr_eval, expr_compile, expr_run, expr_free - evaluate arithmetic

       #include <expr.h>

       int expr_eval(const char *expr, double *res, expr_hook *hook);
       Expr *expr_compile(const char *source);
       int expr_run(Expr *compiled, double *res, expr_hook *hook);
       void expr_free(Expr *compiled);

       These functions evaluate arithmetic expressions given as a string.  All
       values used in the expression (constants, any symbols, functions and
       variables provided by the hook function, and the result of the
       expression) are floating point values of type double.

       An expression may contain operators + (add or sign), - (subtract or
       sign), * (multiply), / (divide), and % (remainder), may use parentheses
       for grouping, may express constants using C floating point and integer
       syntax, and may use symbols (variables, constants, or whatever; the
       meaning is determined by a hook function) and functions (i.e., a symbol
       followed by an argument list in parentheses).  The expression may also
       be an assignment, which gives a new value to a symbol (if the hook
       function allows it).

       The exact syntax of the expression using BNF is:

            assignment = symbol '=' expr
                      | expr.
            expr = term '+' expr
                      | term '-' expr
                      | term.
            term = factor '*' term
                      | factor '/' term
                      | factor '%' term
                      | factor.
            factor = simple_expr
                      | '-' simple_expr.
                      | '+' simple_expr.
            simple_expr = constant
                      | symbol
                      | symbol '(' arglist ')'
                      | '(' expr ')'.
            arglist = expr | expr ',' arglist.
            constant = integer or float, C syntax.
            symbol = C identifier.

       The expr_compile function will parse a string representation for an
       expression, and will `compile' it into a form that is more efficient to
       execute.  The expr_run function will execute the compiled form of the
       expression, and returns the value of the expression.  The expr_free
       function will free all resources allocated for the compiled form.  Use
       it after the last time you need to evaluate the expression.  The
       expr_eval function will do all three operations mentioned above.  It is
       more convenient to use when you only need to evaluate an expression

       The expr_run and expr_eval functions take as their last argument a
       `hook', or a pointer to a function that will be used to get the value
       of a symbol.  The hook should report an error by returning -1, and
       success by returning 0.  The syntax allows symbols to be given an
       argument list (in parentheses), and the hook is supposed to be prepared
       to handle those cases as well, interpreting the symbol as a function
       and the argument list as its arguments.  (The hook may report an error,
       if a non-function symbol is used as a function, or vice versa, or if
       the argument list is of the wrong length.)  The hook may give any
       semantics is wishes to the symbol, neither the expression syntax nor
       the evaluation code assumes anything.  Useful symbols might be
       trigonometric functions, a random number generator, or the time of the

       Assignments are also handled via the hook.  If the second argument to
       the hook is -1, the hook is supposed to modify the value of the symbol.
       Again, it may give any semantics it wishes (i.e., it needn't actually
       modify it, or it might store a different value, or it might output
       something, or do something totally different), and may report errors by
       returning -1.

       The following function implements a variable, "doug", and a function,

       int hook(const char *sym, int nargs, double *args, double *val) {
            if (strcmp(sym, "doug") == 0) {
                 if (nargs != 0)
                      return -1;
                 *val = 42.0;
            } else if (strcmp(sym, "sum") == 0) {
                 if (nargs != 2)
                      return -1;
                 *val = args[0] + args[1];
            return 0;


       Literature about symbol tables or hash tables might come in handy when
       implementing hooks.

       Only having one data type is restricting.  At least truth values (and
       operators), string expressions, and integers would be nice, if they can
       be folded in nicely, without making the syntax and implementation of
       the function overly baroque.  On the other hand, simplicity has its
       virtue, and the current syntax is powerful enough for most things that
       the author can imagine the system being used for.

       Lars Wirzenius (lars.wirzenius@helsinki.fi)

Publib                       C Programmer's Manual                     EXPR(3)