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);