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