diff options
Diffstat (limited to 'src/cmd/tpic/symtab.c')
-rw-r--r-- | src/cmd/tpic/symtab.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/cmd/tpic/symtab.c b/src/cmd/tpic/symtab.c new file mode 100644 index 00000000..32e3bf0f --- /dev/null +++ b/src/cmd/tpic/symtab.c @@ -0,0 +1,109 @@ +#include <stdio.h> +#include <ctype.h> +#include "pic.h" +#include "y.tab.h" + +YYSTYPE +getvar(char *s) /* return value of variable s (usually pointer) */ +{ + struct symtab *p; + static YYSTYPE bug; + + p = lookup(s); + if (p == NULL) { + if (islower(s[0])) + ERROR "no such variable as %s", s WARNING; + else + ERROR "no such place as %s", s WARNING; + return(bug); + } + return(p->s_val); +} + +double +getfval(char *s) /* return float value of variable s */ +{ + YYSTYPE y; + + y = getvar(s); + return y.f; +} + +void +setfval(char *s, double f) /* set variable s to f */ +{ + struct symtab *p; + + if ((p = lookup(s)) != NULL) + p->s_val.f = f; +} + +struct symtab* +makevar(char *s, int t, YYSTYPE v) /* make variable named s in table */ + /* assumes s is static or from tostring */ +{ + struct symtab *p; + + for (p = stack[nstack].p_symtab; p != NULL; p = p->s_next) + if (strcmp(s, p->s_name) == 0) + break; + if (p == NULL) { /* it's a new one */ + p = (struct symtab *) malloc(sizeof(struct symtab)); + if (p == NULL) + ERROR "out of symtab space with %s", s FATAL; + p->s_next = stack[nstack].p_symtab; + stack[nstack].p_symtab = p; /* stick it at front */ + } + p->s_name = s; + p->s_type = t; + p->s_val = v; + return(p); +} + +struct symtab* +lookup(char *s) /* find s in symtab */ +{ + int i; + struct symtab *p; + + for (i = nstack; i >= 0; i--) /* look in each active symtab */ + for (p = stack[i].p_symtab; p != NULL; p = p->s_next) + if (strcmp(s, p->s_name) == 0) + return(p); + return(NULL); +} + +void +freesymtab(struct symtab *p) /* free space used by symtab at p */ +{ + struct symtab *q; + + for ( ; p != NULL; p = q) { + q = p->s_next; + free(p->s_name); /* assumes done with tostring */ + free((char *)p); + } +} + +void +freedef(char *s) /* free definition for string s */ +{ + struct symtab *p, *q, *op; + + for (p = op = q = stack[nstack].p_symtab; p != NULL; p = p->s_next) { + if (strcmp(s, p->s_name) == 0) { /* got it */ + if (p->s_type != DEFNAME) + break; + if (p == op) /* 1st elem */ + stack[nstack].p_symtab = p->s_next; + else + q->s_next = p->s_next; + free(p->s_name); + free(p->s_val.p); + free((char *)p); + return; + } + q = p; + } + /* ERROR "%s is not defined at this point", s WARNING; */ +} |