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 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 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 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 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 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 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 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 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 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