Operator precedence is roughly the same as the C language.
( ) higher * / + - ^ & | lowerPrefixing integer tokens with minus '-' to indicate a negative value is currently not supported.
Example 3. A Simple Calculator
The following example illustrates how to use the eval module with a hashmap(3m) as a symbol table to make a simple commandline calculator.
#include <stdlib.h> #include <string.h> #include <stdio.h> #include <mba/hashmap.h> #include <mba/eval.h> int symtab_lookup(const unsigned char *key, unsigned long *val, struct hashmap *symtab) { const unsigned char *str; if ((str = hashmap_get(symtab, key))) { *val = strtoul(str, NULL, 0); return 0; } return -1; } int main(void) { struct hashmap symtab; unsigned char buf[1024], *bp = buf; unsigned long result; struct eval *eval = eval_new((symlook_fn)symtab_lookup, &symtab); hashmap_init(&symtab, 0, hash_str, cmp_str, NULL, NULL); while ((*bp = fgetc(stdin)) > 0) { if (*bp == '\n') { *bp = '\0'; bp = strchr(buf, '='); *bp++ = '\0'; eval_expression(eval, bp, bp + strlen(bp), &result); sprintf(bp, "%u", result); printf(" %s=%ld\n", buf, result); hashmap_put(&symtab, strdup(buf), strdup(bp)); bp = buf; } else { bp++; } } return EXIT_SUCCESS; } output: $ ./calc foo=0xffff foo=65535 bar=10 * foo & 0x3333 bar=13106
The eval_new function
Description
#include <mba/eval.h> struct eval *eval_new(symlook_fn symlook, void *context);
typedef int (*symlook_fn)(const tchar *name, unsigned long *val, void *context);The symlook_fn function will be called to resolve any non-numeric symbols and should place the value identified by name into val and return 0. If the symbol is not found -1 should be returned.
The eval_new function can be used repeatedly to evaluate any number of expressions before being destroyed with the eval_del function. The context parameter is passed uninterpreted to the symlook_fn (e.g. a map perhaps).
The eval_del function
Description
#include <mba/eval.h> void eval_del(void *eval);
The eval_eval_expression function
Description
#include <mba/eval.h> int eval_expression(struct eval *eval, const tchar *expr, const tchar *elim, unsigned long *result);