Next: The mfcalc
Lexer, Previous: Grammar Rules for mfcalc
, Up: Multi-Function Calculator: mfcalc
[Contents][Index]
mfcalc
Symbol TableThe multi-function calculator requires a symbol table to keep track of the names and meanings of variables and functions. This doesn’t affect the grammar rules (except for the actions) or the Bison declarations, but it requires some additional C functions for support.
The symbol table itself consists of a linked list of records. Its definition, which is kept in the header calc.h, is as follows. It provides for either functions or variables to be placed in the table.
/* Function type. */ typedef double (func_t) (double);
/* Data type for links in the chain of symbols. */ struct symrec { char *name; /* name of symbol */ int type; /* type of symbol: either VAR or FUN */ union { double var; /* value of a VAR */ func_t *fun; /* value of a FUN */ } value; struct symrec *next; /* link field */ };
typedef struct symrec symrec; /* The symbol table: a chain of 'struct symrec'. */ extern symrec *sym_table; symrec *putsym (char const *name, int sym_type); symrec *getsym (char const *name);
The new version of main
will call init_table
to initialize
the symbol table:
struct init { char const *name; func_t *fun; };
struct init const funs[] = { { "atan", atan }, { "cos", cos }, { "exp", exp }, { "ln", log }, { "sin", sin }, { "sqrt", sqrt }, { 0, 0 }, };
/* The symbol table: a chain of 'struct symrec'. */ symrec *sym_table;
/* Put functions in table. */ static void init_table (void)
{ for (int i = 0; funs[i].name; i++) { symrec *ptr = putsym (funs[i].name, FUN); ptr->value.fun = funs[i].fun; } }
By simply editing the initialization list and adding the necessary include files, you can add additional functions to the calculator.
Two important functions allow look-up and installation of symbols in the
symbol table. The function putsym
is passed a name and the kind
(VAR
or FUN
) of the object to be installed. The object is
linked to the front of the list, and a pointer to the object is returned.
The function getsym
is passed the name of the symbol to look up. If
found, a pointer to that symbol is returned; otherwise zero is returned.
/* The mfcalc code assumes that malloc and realloc always succeed, and that integer calculations never overflow. Production-quality code should not make these assumptions. */ #include <assert.h> #include <stdlib.h> /* malloc, realloc. */ #include <string.h> /* strlen. */
symrec * putsym (char const *name, int sym_type) { symrec *res = (symrec *) malloc (sizeof (symrec)); res->name = strdup (name); res->type = sym_type; res->value.var = 0; /* Set value to 0 even if fun. */ res->next = sym_table; sym_table = res; return res; }
symrec * getsym (char const *name) { for (symrec *p = sym_table; p; p = p->next) if (strcmp (p->name, name) == 0) return p; return NULL; }
Next: The mfcalc
Lexer, Previous: Grammar Rules for mfcalc
, Up: Multi-Function Calculator: mfcalc
[Contents][Index]