EXPR(3) C Programmer's Manual EXPR(3) NAME expr_eval, expr_compile, expr_run, expr_free - evaluate arithmetic expressions SYNOPSIS #include <expr.h> intexpr_eval(const char *expr, double *res, expr_hook *hook); Expr *expr_compile(const char *source); intexpr_run(Expr *compiled, double *res, expr_hook *hook); voidexpr_free(Expr *compiled); DESCRIPTION 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.Theexpr_compilefunction will parse a string representation for an expression, and will `compile' it into a form that is more efficient to execute. Theexpr_runfunction will execute the compiled form of the expression, and returns the value of the expression. Theexpr_freefunction will free all resources allocated for the compiled form. Use it after the last time you need to evaluate the expression. Theexpr_evalfunction will do all three operations mentioned above. It is more convenient to use when you only need to evaluate an expression once. Theexpr_runandexpr_evalfunctions 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 day. 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. EXAMPLES The following function implements a variable, "doug", and a function, "sum". 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; } SEE ALSO publib(3) Literature about symbol tables or hash tables might come in handy when implementing hooks. BUGS 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. AUTHOR Lars Wirzenius (lars.wirzenius@helsinki.fi) Publib C Programmer's Manual EXPR(3)