|  | #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; */ | 
|  | } |