xref: /plan9/sys/src/cmd/pic/symtab.c (revision 3e12c5d1bb89fc02707907988834ef147769ddaf)
1*3e12c5d1SDavid du Colombier #include <stdio.h>
2*3e12c5d1SDavid du Colombier #include <stdlib.h>
3*3e12c5d1SDavid du Colombier #include <ctype.h>
4*3e12c5d1SDavid du Colombier #include <string.h>
5*3e12c5d1SDavid du Colombier #include "pic.h"
6*3e12c5d1SDavid du Colombier #include "y.tab.h"
7*3e12c5d1SDavid du Colombier 
getvar(char * s)8*3e12c5d1SDavid du Colombier YYSTYPE getvar(char *s)	/* return value of variable s (usually pointer) */
9*3e12c5d1SDavid du Colombier {
10*3e12c5d1SDavid du Colombier 	struct symtab *p;
11*3e12c5d1SDavid du Colombier 	static YYSTYPE bug;
12*3e12c5d1SDavid du Colombier 
13*3e12c5d1SDavid du Colombier 	p = lookup(s);
14*3e12c5d1SDavid du Colombier 	if (p == NULL) {
15*3e12c5d1SDavid du Colombier 		if (islower(s[0]))
16*3e12c5d1SDavid du Colombier 			ERROR "no such variable as %s", s WARNING;
17*3e12c5d1SDavid du Colombier 		else
18*3e12c5d1SDavid du Colombier 			ERROR "no such place as %s", s WARNING;
19*3e12c5d1SDavid du Colombier 		return(bug);
20*3e12c5d1SDavid du Colombier 	}
21*3e12c5d1SDavid du Colombier 	return(p->s_val);
22*3e12c5d1SDavid du Colombier }
23*3e12c5d1SDavid du Colombier 
getfval(char * s)24*3e12c5d1SDavid du Colombier double getfval(char *s)	/* return float value of variable s */
25*3e12c5d1SDavid du Colombier {
26*3e12c5d1SDavid du Colombier 	YYSTYPE y;
27*3e12c5d1SDavid du Colombier 
28*3e12c5d1SDavid du Colombier 	y = getvar(s);
29*3e12c5d1SDavid du Colombier 	return y.f;
30*3e12c5d1SDavid du Colombier }
31*3e12c5d1SDavid du Colombier 
setfval(char * s,double f)32*3e12c5d1SDavid du Colombier void setfval(char *s, double f)	/* set variable s to f */
33*3e12c5d1SDavid du Colombier {
34*3e12c5d1SDavid du Colombier 	struct symtab *p;
35*3e12c5d1SDavid du Colombier 
36*3e12c5d1SDavid du Colombier 	if ((p = lookup(s)) != NULL)
37*3e12c5d1SDavid du Colombier 		p->s_val.f = f;
38*3e12c5d1SDavid du Colombier }
39*3e12c5d1SDavid du Colombier 
makevar(char * s,int t,YYSTYPE v)40*3e12c5d1SDavid du Colombier struct symtab *makevar(char *s, int t, YYSTYPE v)	/* make variable named s in table */
41*3e12c5d1SDavid du Colombier 		/* assumes s is static or from tostring */
42*3e12c5d1SDavid du Colombier {
43*3e12c5d1SDavid du Colombier 	struct symtab *p;
44*3e12c5d1SDavid du Colombier 
45*3e12c5d1SDavid du Colombier 	for (p = stack[nstack].p_symtab; p != NULL; p = p->s_next)
46*3e12c5d1SDavid du Colombier 		if (strcmp(s, p->s_name) == 0)
47*3e12c5d1SDavid du Colombier 			break;
48*3e12c5d1SDavid du Colombier 	if (p == NULL) {	/* it's a new one */
49*3e12c5d1SDavid du Colombier 		p = (struct symtab *) malloc(sizeof(struct symtab));
50*3e12c5d1SDavid du Colombier 		if (p == NULL)
51*3e12c5d1SDavid du Colombier 			ERROR "out of symtab space with %s", s FATAL;
52*3e12c5d1SDavid du Colombier 		p->s_next = stack[nstack].p_symtab;
53*3e12c5d1SDavid du Colombier 		stack[nstack].p_symtab = p;	/* stick it at front */
54*3e12c5d1SDavid du Colombier 	}
55*3e12c5d1SDavid du Colombier 	p->s_name = s;
56*3e12c5d1SDavid du Colombier 	p->s_type = t;
57*3e12c5d1SDavid du Colombier 	p->s_val = v;
58*3e12c5d1SDavid du Colombier 	return(p);
59*3e12c5d1SDavid du Colombier }
60*3e12c5d1SDavid du Colombier 
lookup(char * s)61*3e12c5d1SDavid du Colombier struct symtab *lookup(char *s)	/* find s in symtab */
62*3e12c5d1SDavid du Colombier {
63*3e12c5d1SDavid du Colombier 	int i;
64*3e12c5d1SDavid du Colombier 	struct symtab *p;
65*3e12c5d1SDavid du Colombier 
66*3e12c5d1SDavid du Colombier 	for (i = nstack; i >= 0; i--)	/* look in each active symtab */
67*3e12c5d1SDavid du Colombier 		for (p = stack[i].p_symtab; p != NULL; p = p->s_next)
68*3e12c5d1SDavid du Colombier 			if (strcmp(s, p->s_name) == 0)
69*3e12c5d1SDavid du Colombier 				return(p);
70*3e12c5d1SDavid du Colombier 	return(NULL);
71*3e12c5d1SDavid du Colombier }
72*3e12c5d1SDavid du Colombier 
freesymtab(struct symtab * p)73*3e12c5d1SDavid du Colombier void freesymtab(struct symtab *p)	/* free space used by symtab at p */
74*3e12c5d1SDavid du Colombier {
75*3e12c5d1SDavid du Colombier 	struct symtab *q;
76*3e12c5d1SDavid du Colombier 
77*3e12c5d1SDavid du Colombier 	for ( ; p != NULL; p = q) {
78*3e12c5d1SDavid du Colombier 		q = p->s_next;
79*3e12c5d1SDavid du Colombier 		free(p->s_name);	/* assumes done with tostring */
80*3e12c5d1SDavid du Colombier 		free((char *)p);
81*3e12c5d1SDavid du Colombier 	}
82*3e12c5d1SDavid du Colombier }
83*3e12c5d1SDavid du Colombier 
freedef(char * s)84*3e12c5d1SDavid du Colombier void freedef(char *s)	/* free definition for string s */
85*3e12c5d1SDavid du Colombier {
86*3e12c5d1SDavid du Colombier 	struct symtab *p, *q, *op;
87*3e12c5d1SDavid du Colombier 
88*3e12c5d1SDavid du Colombier 	for (p = op = q = stack[nstack].p_symtab; p != NULL; p = p->s_next) {
89*3e12c5d1SDavid du Colombier 		if (strcmp(s, p->s_name) == 0) { 	/* got it */
90*3e12c5d1SDavid du Colombier 			if (p->s_type != DEFNAME)
91*3e12c5d1SDavid du Colombier 				break;
92*3e12c5d1SDavid du Colombier 			if (p == op)	/* 1st elem */
93*3e12c5d1SDavid du Colombier 				stack[nstack].p_symtab = p->s_next;
94*3e12c5d1SDavid du Colombier 			else
95*3e12c5d1SDavid du Colombier 				q->s_next = p->s_next;
96*3e12c5d1SDavid du Colombier 			free(p->s_name);
97*3e12c5d1SDavid du Colombier 			free(p->s_val.p);
98*3e12c5d1SDavid du Colombier 			free((char *)p);
99*3e12c5d1SDavid du Colombier 			return;
100*3e12c5d1SDavid du Colombier 		}
101*3e12c5d1SDavid du Colombier 		q = p;
102*3e12c5d1SDavid du Colombier 	}
103*3e12c5d1SDavid du Colombier 	/* ERROR "%s is not defined at this point", s WARNING; */
104*3e12c5d1SDavid du Colombier }
105