This is a term compiler that compiles mathematical terms like 5*(sin(x)+3)^2 and evaluates them. It was originally written as a schoolar project but has resulted in a small term parsing library now. It is written in portable ANSI C and pretty easy to use. The following example (that is also included in the source tarball) should be pretty self-explanatory.
#include "term.h" #include <stdlib.h> #include <stdio.h> #include <math.h> /* * Compile with 'gcc -o term_example example.c term.o -lm' after having * compiled term.c to term.o. */ int main(int argc, char* argv[]) { TermError* error = NULL; /* Creates a new term context that is used to store and lookup * user-defined variables */ TermContext* ctx = term_context_new(); /* Creates a new variable in the given context that is called x. The * variable will automatically be freed when the context is * destroyed. */ TermVariable* var = term_context_register_variable(ctx, "x"); /* This compiles the given string into an abstract expression object. * Note that context is an optional parameter. You may pass in NULL * if you do not need any variables. */ TermExpression* expr = term_expression_new( "5*(sin(x)+3)^2", ctx, &error ); /* term_expression_new() returns NULL when an error occured. */ if(expr == NULL) { /* The error value is now set */ fprintf(stderr, "%s\n", error->message); /* We are responsible for freeing the error. If we do not like * any error information we may also pass NULL for the error * parameter in term_expression_new() and thus have not to * free the error. */ term_error_free(error); } else { /* Defines a value for the previously registered variable */ term_variable_set_value(var, M_PI / 2.0); /* Evaluates the expression and prints it to stdout */ fprintf( stdout, "5*(sin(%f)+3)^2 = %f\n", term_variable_get_value(var), term_expression_eval(expr) ); /* We may now change the variable's value and evaluate the * expression again without recompiling it. */ /* Remember to free the compiled expression when we are done */ term_expression_free(expr); } /* The context needs also to be freed */ term_context_free(ctx); return EXIT_SUCCESS; }
If I find some time and motivation I will probably add some API to register custom functions and to print a compiled term in lexical form. I also considered using the GMP library to support arbitrary floating point precision.
The source code is licensed under the GNU LGPL. If you have anything to say about this piece of software, feel free to contact me (armin at arbur dot net).