1 #ifndef lint
2 static char *sccsid ="util.c	(CWI)	1.1	85/03/01";
3 #endif
4 #include "ideal.h"
5 #include "y.tab.h"
6 
7 #define SYMSIZE	250
8 
9 static char *symtab[SYMSIZE]	= {
10 	"(unnamed)"
11 };
12 static int syminstal	= 1;
13 
14 int lookup(identifier)
15 char *identifier;
16 {
17 	register int i;
18 	i = 0;
19 	symtab[syminstal] = identifier;
20 	while (strcmp(identifier, symtab[i]))
21 		i++;
22 	if (i == syminstal) {
23 		dprintf "installing NAME: %s\n", identifier);
24 		if (i < SYMSIZE) {
25 			if (!(symtab[i] = malloc((unsigned) (1+strlen(identifier))))) {
26 				fprintf(stderr,"ideal: memory overflow in lookup\n");
27 				exit(1);
28 			}
29 		}
30 		else {
31 			fprintf(stderr,"ideal: too many identifiers\n");
32 			exit(1);
33 		}
34 		strcpy(symtab[syminstal++], identifier);
35 	}
36 	return(i);
37 }
38 
39 char *idprint(idnum)
40 int idnum;
41 {
42 	if ((idnum > -1) && (idnum < syminstal))
43 		return(symtab[idnum]);
44 	else {
45 		fprintf(stderr,"ideal: invalid identifier index: %d\n", idnum);
46 		return(NULL);
47 	}
48 }
49 
50 extern BOXPTR boxlist;
51 
52 BOXPTR findbox (sought, alarm)
53 int sought,
54 	alarm;
55 {
56 	BOXPTR bxwalk;
57 	for (bxwalk = boxlist;
58 		bxwalk && (bxwalk->name != sought);
59 		bxwalk = bxwalk->next)
60 		;
61 	if (!bxwalk) {
62 		if (!alarm)
63 			fprintf (stderr, "ideal: undefined box:  %s\n", idprint (sought));
64 		return (boxgen (sought, (STMTPTR) NULL));
65 	} else
66 		return (bxwalk);
67 }
68 
69 
70 INTLPTR varfind (name, givennoad)
71 int name;
72 NOADPTR givennoad;
73 {
74 	/* finds simple variable 'name' from 'givennoad' */
75 	register VARPTR varwalk;
76 	if (!givennoad) {
77 		fprintf (stderr, "ideal: no such variable, %s\n  >>>Returning 0.0\n",
78 			idprint (name)
79 		);
80 		return (commagen (0.0, 0.0));
81 	}
82 	dprintf "Looking for %s in %s\n", idprint (name), idprint (givennoad->defnode->name));
83 	for (varwalk = givennoad->edgevarlist;
84 		varwalk && THENAME(varwalk) != name;
85 		varwalk = varwalk->next)
86 		;
87 	if (!varwalk)
88 		for (varwalk = givennoad->boxvarlist;
89 			varwalk && THENAME(varwalk) != name;
90 			varwalk = varwalk->next)
91 			;
92 	if (!varwalk)
93 		return (varfind (name, givennoad->father));
94 	else
95 		return (intlgen (
96 			';',
97 			(EXPR) depadd ((DEPPTR) NULL, 0.0, varwalk->deplist, 1.0),
98 			(EXPR) depadd ((DEPPTR) NULL, 0.0, varwalk->next->deplist, 1.0)
99 			));
100 }
101 
102 INTLPTR pathfind (ptname, givennoad)
103 NAMEPTR ptname;
104 NOADPTR givennoad;
105 {
106 	/* finds compound variable 'ptname' from 'givennoad' */
107 	int i;
108 	STMTPTR putwalk;
109 	NOADPTR noadwalk;
110 	if (!ptname->next)
111 		return (varfind (ptname->name, givennoad));
112 	for (i = 0; i < 2; i++) {
113 		noadwalk = givennoad->son;
114 		for (putwalk = nextstmt (PUT, givennoad->defnode->parm->stmtlist);
115 			putwalk && ((PUTPTR) putwalk->stmt)->name != ptname->name;
116 			putwalk = nextstmt (PUT, putwalk->next))
117 			noadwalk = noadwalk->brother;
118 		if (!putwalk)
119 			for (putwalk = nextstmt (PUT, findbox (givennoad->defnode->parm->name,FALSE)->stmtlist);
120 				putwalk && ((PUTPTR) putwalk->stmt)->name != ptname->name;
121 				putwalk = nextstmt (PUT, putwalk->next))
122 				noadwalk = noadwalk->brother;
123 		if (putwalk) {
124 			dprintf "found %s, now looking for %s\n",
125 				idprint (ptname->name),
126 				idprint (ptname->next->name)
127 			);
128 			return (pathfind (ptname->next, noadwalk));
129 		}
130 		if (!(givennoad = givennoad->father)) {
131 			dprintf "reached root of noad tree\n");
132 			break;
133 		} else {
134 			dprintf "looking for %s at father of %s\n",
135 				idprint (ptname->name),
136 				idprint (givennoad->defnode->name)
137 			);
138 		}
139 	}
140 	fprintf (stderr, "ideal: invalid variable path name beginning %s\n  >>>Returning 0.0\n",
141 		idprint (ptname->name));
142 	return (commagen (0.0, 0.0));
143 }
144 
145 BOXPTR tail (head)
146 BOXPTR head;
147 {
148 	while (head->next)
149 		head = head->next;
150 	return (head);
151 }
152 
153 void forget (sought)
154 int sought;
155 {
156 	BOXPTR bxwalk;
157 	BOXPTR prevbox;
158 	prevbox = NULL;
159 	for (bxwalk = boxlist;
160 		bxwalk && (bxwalk->name != sought);
161 		bxwalk = bxwalk->next)
162 		prevbox = bxwalk;
163 	if (bxwalk) {
164 		if (prevbox) {
165 			prevbox->next = bxwalk->next;
166 		} else {
167 			boxlist = bxwalk->next;
168 		}
169 		boxfree (bxwalk);
170 	}
171 }
172 
173 void exprprint (exprn)
174 EXPR exprn;
175 {
176 	INTLPTR intl;
177 	EXTLPTR extl;
178 	if (!exprn)
179 		return;
180 	if (((EXTLPTR) exprn)->leaf) {
181 		extl = (EXTLPTR) exprn;
182 		switch (extl->kind) {
183 		case PATH:
184 			{
185 			NAMEPTR pathwalk;
186 			for (pathwalk = extl->info.path;
187 				pathwalk->next;
188 				pathwalk = pathwalk->next)
189 				fprintf (stderr, "%s.", idprint (pathwalk->name));
190 			fprintf (stderr, "%s", idprint (pathwalk->name));
191 			}
192 			break;
193 		case CONST:
194 			fprintf (stderr, "%f", extl->info.const);
195 			break;
196 		}
197 	} else {
198 		intl = (INTLPTR) exprn;
199 		switch (intl->oper) {
200 		case NAME:
201 			fprintf (stderr, "%s(", idprint ((int) intl->left));
202 			exprprint (((EXPRPTR) intl->right)->expr);
203 			fprintf (stderr, ")");
204 			break;
205 		case '=':
206 		case '~':
207 			exprprint ((EXPR) intl->right);
208 			break;
209 		case ',':
210 			fprintf (stderr, "(");
211 			exprprint ((EXPR) intl->left);
212 			fprintf (stderr, ",");
213 			exprprint ((EXPR) intl->right);
214 			fprintf (stderr, ")");
215 			break;
216 		case ';':
217 			fprintf (stderr, "(");
218 			depprint ((DEPPTR) intl->left);
219 			fprintf (stderr, ",");
220 			depprint ((DEPPTR) intl->right);
221 			fprintf (stderr, ")");
222 			break;
223 		default:
224 			fprintf (stderr, "(");
225 			exprprint ((EXPR) intl->left);
226 			fprintf (stderr, " %c ", intl->oper);
227 			exprprint ((EXPR) intl->right);
228 			fprintf (stderr, ")");
229 			break;
230 		}
231 	}
232 }
233 
234 STMTPTR nextstmt (kind, curstmt)
235 int kind;
236 STMTPTR curstmt;
237 {
238 	register STMTPTR stmtwalk;
239 	stmtwalk = curstmt;
240 	for (stmtwalk;
241 		stmtwalk && (stmtwalk->kind != kind);
242 		stmtwalk = stmtwalk->next)
243 		;
244 	return (stmtwalk);
245 }
246 
247 EXPR bracket (alpha, x, y)
248 EXPR alpha,
249 	x,
250 	y;
251 {
252 	return (
253 		(EXPR) intlgen (
254 			'+',
255 			x,
256 			(EXPR) intlgen (
257 				'*',
258 				alpha,
259 				(EXPR) intlgen (
260 					'-',
261 					y,
262 					x
263 				)
264 			)
265 		)
266 	);
267 }
268 
269 void depprint (depnd)
270 DEPPTR depnd;
271 {
272 	for (depnd;
273 		depnd->next;
274 		depnd = depnd->next)
275 		fprintf (stderr, "%f %s(%s) + ",
276 			depnd->coeff,
277 			ISREAL(depnd->var)?"re":"im",
278 			idprint (THENAME(depnd->var))
279 		);
280 	fprintf (stderr, "%f", depnd->coeff);
281 	if (depnd->var)
282 		fprintf (stderr, " %s(%s)",
283 			ISREAL(depnd->var)?"re":"im",
284 			idprint (THENAME(depnd->var))
285 		);
286 }
287 
288 void dexch (a,b)
289 double *a;
290 double *b;
291 {
292 	double temp;
293 	temp = *a;
294 	*a = *b;
295 	*b = temp;
296 }
297 
298 void fexch (a,b)
299 float *a;
300 float *b;
301 {
302 	float temp;
303 	temp = *a;
304 	*a = *b;
305 	*b = temp;
306 }
307 
308 float rprin (angle)
309 float angle;
310 {
311 	while (angle < 0.0)
312 		angle += 2*PI;
313 	while (angle > 2*PI + EPSILON)
314 		angle -= 2*PI;
315 	return (angle);
316 }
317 
318 /*
319 float dprin (angle)
320 float angle;
321 {
322 	while (angle < 0.0)
323 		angle += 360;
324 	while (angle > 2*PI)
325 		angle -= 360;
326 	return (angle);
327 }
328 */
329 
330 void angorder (startang, midang, endang)
331 float *startang;
332 float midang;
333 float *endang;
334 {
335 	if (
336 		((*endang < midang) && (midang < *startang))
337 	||	((*startang < *endang) && (*endang < midang))
338 	||	((midang < *startang) && (*startang < *endang))
339 	)
340 		fexch (startang, endang);
341 }
342 
343 STMTPTR reverse (stmtlist)
344 STMTPTR stmtlist;
345 {
346 	STMTPTR curstmt, prevstmt, temp;
347 	prevstmt = curstmt = stmtlist;
348 	temp = NULL;
349 	while (curstmt) {
350 		curstmt = prevstmt->next;
351 		prevstmt->next = temp;
352 		temp = prevstmt;
353 		prevstmt = curstmt;
354 	}
355 	return (temp);
356 }
357 
358 void impossible (msg)
359 char *msg;
360 {
361 	fprintf (stderr, "ideal: %s: can't happen\n", msg);
362 	exit (1);
363 }
364