Example 2. A Symbol Lookup Table
The following example illustrates how to use the eval module with a symbol table to evaluate a simple arithmetic expression from the commandline.
#include <stdlib.h>
#include <stdio.h>
#include <mba/eval.h>
#include <mba/msgno.h>
struct {
const tchar *name;
const unsigned long val;
} symtab[] = {
{ _T("N"), 3 },
{ _T("MAXVALUES"), 0xFFFF },
{ _T("NODEF"), -1 },
};
int
symbol_lookup(const tchar *name, unsigned long *val)
{
int i;
for (i = 0; symtab[i].name; i++) {
if (tcscmp(symtab[i].name, name) == 0) {
*val = symtab[i].val;
return 0;
}
}
return -1;
}
int
main(int argc, char *argv[])
{
unsigned long result;
struct eval *eval = eval_new(&symbol_lookup);
if (eval_expression(eval, argv[1], argv[1] + strlen(argv[1]), &result) == -1) {
MSG("");
return EXIT_FAILURE;
}
printf("%s = %ld\n", argv[1], result);
return EXIT_SUCCESS;
}
output:
$ ./eval '(5 + 3) * N'
(5 + 3) * N = 24
Large tables should be generated with a program that sorts the identifiers so the the symlook_fn can perform a binary search (see end of wcwidth.c).
The eval_new function
Description
#include <mba/eval.h> struct eval *eval_new(symlook_fn symlook);
typedef int (*symlook_fn)(const tchar *name, unsigned long *val);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 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);