1*18185Sjaap #ifndef lint
2*18185Sjaap static char *sccsid ="action.c	(CWI)	1.1	85/03/01";
3*18185Sjaap #endif
4*18185Sjaap #include "ideal.h"
5*18185Sjaap #include "y.tab.h"
6*18185Sjaap 
rbuild(noadtree,linelist)7*18185Sjaap LINEPTR rbuild (noadtree, linelist)
8*18185Sjaap NOADPTR noadtree;
9*18185Sjaap LINEPTR linelist;
10*18185Sjaap {
11*18185Sjaap 	STMTPTR slist[2];
12*18185Sjaap 	STMTPTR curstmt, opqstmt;
13*18185Sjaap 	NOADPTR nextnoad;
14*18185Sjaap 	int i;
15*18185Sjaap 	slist[0] = noadtree->defnode->parm->stmtlist;
16*18185Sjaap 	slist[1] = findbox (noadtree->defnode->parm->name,FALSE)->stmtlist;
17*18185Sjaap 	nextnoad = noadtree->son;
18*18185Sjaap 	if ((opqstmt = nextstmt (OPAQUE, slist[0])) || (opqstmt = nextstmt (OPAQUE, slist[1])))
19*18185Sjaap 		linelist = opqact (opqstmt, noadtree, linelist);
20*18185Sjaap 	if (noadtree->defnode->parm->name == lookup ("circle"))
21*18185Sjaap 		linelist = circact (noadtree, linelist);
22*18185Sjaap 	else if (noadtree->defnode->parm->name == lookup ("arc"))
23*18185Sjaap 		linelist = arcact (noadtree, linelist);
24*18185Sjaap 	for (i = 0; i < 2; i ++)
25*18185Sjaap 	for (curstmt = slist[i]; curstmt; curstmt = curstmt->next) {
26*18185Sjaap 	switch (curstmt->kind) {
27*18185Sjaap 		case '=':
28*18185Sjaap 			break;
29*18185Sjaap 		case CONN:
30*18185Sjaap 			linelist = connact (
31*18185Sjaap 				(EXPRPTR) curstmt->stmt,
32*18185Sjaap 				noadtree,
33*18185Sjaap 				linelist
34*18185Sjaap 			);
35*18185Sjaap 			break;
36*18185Sjaap 		case USING:
37*18185Sjaap 			linelist = penact (
38*18185Sjaap 				(PENPTR) curstmt->stmt,
39*18185Sjaap 				noadtree,
40*18185Sjaap 				linelist
41*18185Sjaap 			);
42*18185Sjaap 			break;
43*18185Sjaap 		case PUT:
44*18185Sjaap 			if (((PUTPTR)curstmt->stmt)->p_or_c == PUT)
45*18185Sjaap 				linelist = rbuild (nextnoad, linelist);
46*18185Sjaap 			else if (((PUTPTR)curstmt->stmt)->p_or_c == CONSTRUCT)
47*18185Sjaap 				nextnoad->linelist = rbuild (nextnoad, nextnoad->linelist);
48*18185Sjaap 			else impossible ("rbuild (PUT)");
49*18185Sjaap 			nextnoad = nextnoad->brother;
50*18185Sjaap 			break;
51*18185Sjaap                         case DRAW:
52*18185Sjaap 			linelist = drawact (
53*18185Sjaap 				(MISCPTR) curstmt->stmt,
54*18185Sjaap 				noadtree,
55*18185Sjaap 				linelist
56*18185Sjaap 			);
57*18185Sjaap 			break;
58*18185Sjaap 		case STRING:
59*18185Sjaap 			linelist = stract (
60*18185Sjaap 				(STRPTR) curstmt->stmt,
61*18185Sjaap 				noadtree,
62*18185Sjaap 				linelist
63*18185Sjaap 			);
64*18185Sjaap 			break;
65*18185Sjaap 		case SPLINE:
66*18185Sjaap 			linelist = splact (
67*18185Sjaap 				(EXPRPTR) curstmt->stmt,
68*18185Sjaap 				noadtree,
69*18185Sjaap 				linelist
70*18185Sjaap 			);
71*18185Sjaap 			break;
72*18185Sjaap 		case OPAQUE:
73*18185Sjaap 			break;
74*18185Sjaap 		case BDLIST:
75*18185Sjaap 			break;
76*18185Sjaap 		case VAR:
77*18185Sjaap 			break;
78*18185Sjaap 		default:
79*18185Sjaap 			impossible ("rbuild");
80*18185Sjaap 		}
81*18185Sjaap 	}
82*18185Sjaap 	return (linelist);
83*18185Sjaap }
84*18185Sjaap 
build(noadtree,linelist)85*18185Sjaap LINEPTR build (noadtree, linelist)
86*18185Sjaap NOADPTR noadtree;
87*18185Sjaap LINEPTR linelist;
88*18185Sjaap {
89*18185Sjaap 	LINEPTR retval;
90*18185Sjaap 	if (when_bug & 040) bug_on;
91*18185Sjaap 	retval = rbuild (noadtree, linelist);
92*18185Sjaap 	bug_off;
93*18185Sjaap 	return (retval);
94*18185Sjaap }
95*18185Sjaap 
connact(connstmt,noadtree,linelist)96*18185Sjaap LINEPTR connact (connstmt, noadtree, linelist)
97*18185Sjaap EXPRPTR connstmt;
98*18185Sjaap NOADPTR noadtree;
99*18185Sjaap LINEPTR linelist;
100*18185Sjaap {
101*18185Sjaap 	INTLPTR frompt, topt;
102*18185Sjaap 	LINEPTR newline;
103*18185Sjaap 	EXPRPTR linwalk;
104*18185Sjaap 	newline = NULL;
105*18185Sjaap 	frompt = expreval (connstmt->expr, noadtree);
106*18185Sjaap 	linwalk = connstmt->next;
107*18185Sjaap 	while (linwalk) {
108*18185Sjaap 		topt = expreval (linwalk->expr, noadtree);
109*18185Sjaap 		if (!known(frompt) || !known(topt)) {
110*18185Sjaap 			fprintf (stderr, "ideal: indeterminate endpoints\n   >>>conn ignored\n");
111*18185Sjaap 		} else {
112*18185Sjaap 			newline = linegen (
113*18185Sjaap 				Re(frompt), Im(frompt),
114*18185Sjaap 				Re(topt), Im(topt)
115*18185Sjaap 			);
116*18185Sjaap 			dprintf "Adding line (%f,%f) to (%f,%f)\n",
117*18185Sjaap 				Re(frompt), Im(frompt),
118*18185Sjaap 				Re(topt), Im(topt)
119*18185Sjaap 			);
120*18185Sjaap 			newline->next = linelist;
121*18185Sjaap 			linelist = newline;
122*18185Sjaap 		}
123*18185Sjaap 		intlfree (frompt);
124*18185Sjaap 		frompt = topt;
125*18185Sjaap 		linwalk = linwalk->next;
126*18185Sjaap 	}
127*18185Sjaap 	intlfree (topt);
128*18185Sjaap 	return (newline);
129*18185Sjaap }
130*18185Sjaap 
penact(penstmt,noadtree,linelist)131*18185Sjaap LINEPTR penact (penstmt, noadtree, linelist)
132*18185Sjaap PENPTR penstmt;
133*18185Sjaap NOADPTR noadtree;
134*18185Sjaap LINEPTR linelist;
135*18185Sjaap {
136*18185Sjaap 	INTLPTR frompt, topt, copies;
137*18185Sjaap 	LINEPTR newline;
138*18185Sjaap 	frompt = expreval (penstmt->from, noadtree);
139*18185Sjaap 	topt = expreval (penstmt->to, noadtree);
140*18185Sjaap 	copies = expreval (penstmt->copies, noadtree);
141*18185Sjaap 	newline = linelist;
142*18185Sjaap 	if (!known(frompt) || !known(topt) || !known(copies)) {
143*18185Sjaap 		fprintf (stderr, "ideal: indeterminate pen\n   >>>pen ignored\n");
144*18185Sjaap 	} else {
145*18185Sjaap 		PUTNODE dummyput;
146*18185Sjaap 		NOADPTR pennoad;
147*18185Sjaap 		STMTPTR ostmthead;
148*18185Sjaap 		int i;
149*18185Sjaap 
150*18185Sjaap 		dprintf "Drawing pen from (%f,%f) to (%f,%f)\n",
151*18185Sjaap 			Re(frompt),
152*18185Sjaap 			Im(frompt),
153*18185Sjaap 			Re(topt),
154*18185Sjaap 			Im(topt)
155*18185Sjaap 		);
156*18185Sjaap 
157*18185Sjaap 		/* add key statements to beginning of parameter section */
158*18185Sjaap 		dummyput.name = 0;
159*18185Sjaap 		dummyput.parm = penstmt->pen;
160*18185Sjaap 		ostmthead = dummyput.parm->stmtlist;
161*18185Sjaap 		dummyput.parm->stmtlist = stmtgen (
162*18185Sjaap 			'=',
163*18185Sjaap 			(char *) intlgen (
164*18185Sjaap 				'=',
165*18185Sjaap 				(EXPR) extlgen (namegen (lookup ("$pencnt"))),
166*18185Sjaap 				(EXPR) fextlgen (0.0)
167*18185Sjaap 			)
168*18185Sjaap 		);
169*18185Sjaap 		dummyput.parm->stmtlist->next = stmtgen (
170*18185Sjaap 			'=',
171*18185Sjaap 			(char *) intlgen (
172*18185Sjaap 				'=',
173*18185Sjaap 				penstmt->start,
174*18185Sjaap 				bracket (
175*18185Sjaap 					(EXPR) intlgen (
176*18185Sjaap 						'/',
177*18185Sjaap 						(EXPR) extlgen(namegen(lookup("$pencnt"))),
178*18185Sjaap 						(EXPR) copies
179*18185Sjaap 					),
180*18185Sjaap 					(EXPR) frompt,
181*18185Sjaap 					(EXPR) topt
182*18185Sjaap 				)
183*18185Sjaap 			)
184*18185Sjaap 		);
185*18185Sjaap 		dummyput.parm->stmtlist->next->next = stmtgen (
186*18185Sjaap 			'=',
187*18185Sjaap 			(char *) intlgen (
188*18185Sjaap 				'=',
189*18185Sjaap 				penstmt->end,
190*18185Sjaap 				bracket (
191*18185Sjaap 					(EXPR) intlgen (
192*18185Sjaap 						'/',
193*18185Sjaap 						(EXPR) intlgen (
194*18185Sjaap 							'+',
195*18185Sjaap 							(EXPR) extlgen(namegen(lookup("$pencnt"))),
196*18185Sjaap 							(EXPR) fextlgen(1.0)
197*18185Sjaap 						),
198*18185Sjaap 						(EXPR) copies
199*18185Sjaap 					),
200*18185Sjaap 					(EXPR) frompt,
201*18185Sjaap 					(EXPR) topt
202*18185Sjaap 				)
203*18185Sjaap 			)
204*18185Sjaap 		);
205*18185Sjaap 		dummyput.parm->stmtlist->next->next->next = stmtgen (
206*18185Sjaap 			VAR,
207*18185Sjaap 			(char *) namegen (lookup ("$pencnt"))
208*18185Sjaap 		);
209*18185Sjaap 		dummyput.parm->stmtlist->next->next->next->next = ostmthead;
210*18185Sjaap 		/* make N copies */
211*18185Sjaap 		for (i = 0; i < Re(copies); i ++) {
212*18185Sjaap 			((EXTLPTR) ((INTLPTR) dummyput.parm->stmtlist->stmt)->right)->info.const = i;
213*18185Sjaap 			pennoad = buildnoadtree (&dummyput);
214*18185Sjaap 			pennoad->father = noadtree;
215*18185Sjaap 			eqneval (pennoad);
216*18185Sjaap 			nl_eval ();
217*18185Sjaap 			newline = build (pennoad, newline);
218*18185Sjaap 			depvarkill ();
219*18185Sjaap 			noadfree (pennoad);
220*18185Sjaap 		}
221*18185Sjaap 	if (dummyput.parm->stmtlist->next->next->next->next != ostmthead)
222*18185Sjaap 		impossible ("penact");
223*18185Sjaap 	dummyput.parm->stmtlist->next->next->next->next = NULL;
224*18185Sjaap 	/* will have to let garbage collector get dummyput.parm */
225*18185Sjaap 	penstmt->pen->stmtlist = ostmthead;
226*18185Sjaap 	}
227*18185Sjaap 	intlfree (frompt);
228*18185Sjaap 	intlfree (topt);
229*18185Sjaap 	intlfree (copies);
230*18185Sjaap 	return (newline);
231*18185Sjaap }
232*18185Sjaap 
drawact(noadname,noadtree,linelist)233*18185Sjaap LINEPTR drawact (noadname, noadtree, linelist)
234*18185Sjaap MISCPTR noadname;
235*18185Sjaap NOADPTR noadtree;
236*18185Sjaap LINEPTR linelist;
237*18185Sjaap {
238*18185Sjaap 	NOADPTR noadwalk;
239*18185Sjaap 	LINEPTR nuline;
240*18185Sjaap 	for (noadwalk = noadtree->son;
241*18185Sjaap 		noadwalk && (noadwalk->defnode->name != noadname->info);
242*18185Sjaap 		noadwalk = noadwalk->brother)
243*18185Sjaap 		dprintf "%s %s",
244*18185Sjaap 			idprint(noadwalk->defnode->name),
245*18185Sjaap 			idprint(noadname->info)
246*18185Sjaap 		);
247*18185Sjaap 		;
248*18185Sjaap 	if (noadwalk) {
249*18185Sjaap 		((LINEPTR) tail ((BOXPTR) noadwalk->linelist))->next = linelist;
250*18185Sjaap 		nuline = noadwalk->linelist;
251*18185Sjaap 		noadwalk->linelist = NULL;
252*18185Sjaap 		return (nuline);
253*18185Sjaap 
254*18185Sjaap 	} else {
255*18185Sjaap 		fprintf (stderr, "ideal: can't find %s to draw it\n",
256*18185Sjaap 			idprint (noadname->info)
257*18185Sjaap 		);
258*18185Sjaap 		return (linelist);
259*18185Sjaap 	}
260*18185Sjaap }
261*18185Sjaap 
stract(strstmt,noadtree,linelist)262*18185Sjaap LINEPTR stract (strstmt, noadtree, linelist)
263*18185Sjaap STRPTR strstmt;
264*18185Sjaap NOADPTR noadtree;
265*18185Sjaap LINEPTR linelist;
266*18185Sjaap {
267*18185Sjaap 	LINEPTR newline;
268*18185Sjaap 	INTLPTR atpt;
269*18185Sjaap 	atpt = expreval (strstmt->at, noadtree);
270*18185Sjaap 	if (!known(atpt)){
271*18185Sjaap 		fprintf (stderr, "ideal: indeterminate string location\n   >>>string ignored\n");
272*18185Sjaap 		newline = linelist;
273*18185Sjaap 	} else {
274*18185Sjaap 		dprintf "Adding string %s\n",
275*18185Sjaap 			strstmt->string);
276*18185Sjaap 		newline = textgen (
277*18185Sjaap 			strstmt->command,
278*18185Sjaap 			strstmt->string,
279*18185Sjaap 			Re(atpt),
280*18185Sjaap 			Im(atpt)
281*18185Sjaap 		);
282*18185Sjaap 		newline->next = linelist;
283*18185Sjaap 	}
284*18185Sjaap 	intlfree (atpt);
285*18185Sjaap 	return (newline);
286*18185Sjaap }
287*18185Sjaap 
circact(noadtree,linelist)288*18185Sjaap LINEPTR circact (noadtree, linelist)
289*18185Sjaap NOADPTR noadtree;
290*18185Sjaap LINEPTR linelist;
291*18185Sjaap {
292*18185Sjaap 	LINEPTR newline;
293*18185Sjaap 	INTLPTR radius, center;
294*18185Sjaap 	radius = varfind (lookup ("radius"), noadtree);
295*18185Sjaap 	center = varfind (lookup ("center"), noadtree);
296*18185Sjaap 	if (!known(radius) || !known(center)) {
297*18185Sjaap 		fprintf (stderr, "ideal: indeterminate circle\n   >>>ignored\n");
298*18185Sjaap 		newline = linelist;
299*18185Sjaap 	} else {
300*18185Sjaap 		float rad;
301*18185Sjaap 		rad = Re(radius);
302*18185Sjaap 		dprintf "Adding circle %f %f %f\n",
303*18185Sjaap 			Re(center),
304*18185Sjaap 			Im(center),
305*18185Sjaap 			rad
306*18185Sjaap 		);
307*18185Sjaap 		newline = circgen (
308*18185Sjaap 			Re(center),
309*18185Sjaap 			Im(center),
310*18185Sjaap 			rad
311*18185Sjaap 		);
312*18185Sjaap 		newline->next = linelist;
313*18185Sjaap 	}
314*18185Sjaap 	intlfree (radius);
315*18185Sjaap 	intlfree (center);
316*18185Sjaap 	return (newline);
317*18185Sjaap }
318*18185Sjaap 
arcact(noadtree,linelist)319*18185Sjaap LINEPTR arcact (noadtree, linelist)
320*18185Sjaap NOADPTR noadtree;
321*18185Sjaap LINEPTR linelist;
322*18185Sjaap {
323*18185Sjaap 	LINEPTR newline;
324*18185Sjaap 	INTLPTR start, center, end;
325*18185Sjaap 	INTLPTR temp;
326*18185Sjaap 	float radius;
327*18185Sjaap 	float startang, midang, endang;
328*18185Sjaap 	center = varfind (lookup ("center"), noadtree);
329*18185Sjaap 	start = varfind (lookup ("start"), noadtree);
330*18185Sjaap 	end = varfind (lookup ("end"), noadtree);
331*18185Sjaap 	temp = varfind (lookup ("startang"), noadtree);
332*18185Sjaap 	startang = Re(temp);
333*18185Sjaap 	tryfree(temp);
334*18185Sjaap 	temp = varfind (lookup ("midang"), noadtree);
335*18185Sjaap 	midang = Re(temp);
336*18185Sjaap 	if (fabs(midang - startang) < EPSILON)
337*18185Sjaap 		midang = startang;
338*18185Sjaap 	tryfree(temp);
339*18185Sjaap 	temp = varfind (lookup ("endang"), noadtree);
340*18185Sjaap 	endang = Re(temp);
341*18185Sjaap 	tryfree(temp);
342*18185Sjaap 	if (!radflag) {
343*18185Sjaap 		dtor(startang);
344*18185Sjaap 		dtor(midang);
345*18185Sjaap 		dtor(endang);
346*18185Sjaap 	}
347*18185Sjaap 	startang = rprin (startang);
348*18185Sjaap 	midang = rprin (midang);
349*18185Sjaap 	endang = rprin (endang);
350*18185Sjaap 	if (fabs(startang - midang) < EPSILON
351*18185Sjaap 		&& startang > endang)
352*18185Sjaap 		endang += 2*PI;
353*18185Sjaap 	radius = ((DEPPTR) (varfind (lookup ("radius"), noadtree))->left)->coeff;
354*18185Sjaap 	if (!known(center) || !known(start) || !known(end)) {
355*18185Sjaap 		fprintf (stderr, "ideal: indeterminate arc\n   >>>ignored\n");
356*18185Sjaap 		newline = linelist;
357*18185Sjaap 	} else {
358*18185Sjaap 		angorder (&startang, midang, &endang);
359*18185Sjaap 		dprintf "Adding arc %f %f %f %f %f\n",
360*18185Sjaap 			Re(center),
361*18185Sjaap 			Im(center),
362*18185Sjaap 			radius,
363*18185Sjaap 			startang,
364*18185Sjaap 			endang
365*18185Sjaap 		);
366*18185Sjaap 		newline = angularc (
367*18185Sjaap 			Re(center),
368*18185Sjaap 			Im(center),
369*18185Sjaap 			radius,
370*18185Sjaap 			startang,
371*18185Sjaap 			endang
372*18185Sjaap 		);
373*18185Sjaap 		newline->next = linelist;
374*18185Sjaap 	}
375*18185Sjaap 	intlfree (center);
376*18185Sjaap 	intlfree (start);
377*18185Sjaap 	intlfree (end);
378*18185Sjaap 	return (newline);
379*18185Sjaap }
380*18185Sjaap 
splact(splstmt,noadtree,linelist)381*18185Sjaap LINEPTR splact (splstmt, noadtree, linelist)
382*18185Sjaap EXPRPTR splstmt;
383*18185Sjaap NOADPTR noadtree;
384*18185Sjaap LINEPTR linelist;
385*18185Sjaap {
386*18185Sjaap 	EXPRNODE knotlist;
387*18185Sjaap 	EXPRPTR knotwalk;
388*18185Sjaap 	EXPRPTR splwalk;
389*18185Sjaap 	LINEPTR nuline;
390*18185Sjaap 
391*18185Sjaap 	if (when_bug & 0200) bug_on;
392*18185Sjaap 	knotwalk = &knotlist;
393*18185Sjaap 	knotwalk->next = NULL;
394*18185Sjaap 	for (splwalk = splstmt;
395*18185Sjaap 		splwalk;
396*18185Sjaap 		splwalk = splwalk->next
397*18185Sjaap 	) {
398*18185Sjaap 		knotwalk->next = exprgen (
399*18185Sjaap 			(EXPR) expreval (
400*18185Sjaap 				splwalk->expr,
401*18185Sjaap 				noadtree
402*18185Sjaap 			)
403*18185Sjaap 		);
404*18185Sjaap 		if (!known(((INTLPTR) knotwalk->next->expr))) {
405*18185Sjaap 			fprintf (stderr, "ideal: unknown spline knot\n   >>>spline ignored\n");
406*18185Sjaap 			return (linelist);
407*18185Sjaap 		}
408*18185Sjaap 		knotwalk = knotwalk->next;
409*18185Sjaap 		dprintf "spline knot: %f %f\n",
410*18185Sjaap 			Re(((INTLPTR) knotwalk->expr)),
411*18185Sjaap 			Im(((INTLPTR) knotwalk->expr))
412*18185Sjaap 		);
413*18185Sjaap 	}
414*18185Sjaap 	nuline = splgen (knotlist.next);
415*18185Sjaap 	nuline->next = linelist;
416*18185Sjaap 	return (nuline);
417*18185Sjaap }
418