#include "ideal.h" #include "y.tab.h" LINEPTR rbuild (noadtree, linelist) NOADPTR noadtree; LINEPTR linelist; { STMTPTR slist[2]; STMTPTR curstmt, opqstmt; NOADPTR nextnoad; int i; slist[0] = noadtree->defnode->parm->stmtlist; slist[1] = findbox (noadtree->defnode->parm->name,FALSE)->stmtlist; nextnoad = noadtree->son; if ((opqstmt = nextstmt (OPAQUE, slist[0])) || (opqstmt = nextstmt (OPAQUE, slist[1]))) linelist = opqact (opqstmt, noadtree, linelist); if (noadtree->defnode->parm->name == lookup ("circle")) linelist = circact (noadtree, linelist); else if (noadtree->defnode->parm->name == lookup ("arc")) linelist = arcact (noadtree, linelist); for (i = 0; i < 2; i ++) for (curstmt = slist[i]; curstmt; curstmt = curstmt->next) { switch (curstmt->kind) { case '=': break; case CONN: linelist = connact ( (EXPRPTR) curstmt->stmt, noadtree, linelist ); break; case USING: linelist = penact ( (PENPTR) curstmt->stmt, noadtree, linelist ); break; case PUT: if (((PUTPTR)curstmt->stmt)->p_or_c == PUT) linelist = rbuild (nextnoad, linelist); else if (((PUTPTR)curstmt->stmt)->p_or_c == CONSTRUCT) nextnoad->linelist = rbuild (nextnoad, nextnoad->linelist); else impossible ("rbuild (PUT)"); nextnoad = nextnoad->brother; break; case DRAW: linelist = drawact ( (MISCPTR) curstmt->stmt, noadtree, linelist ); break; case STRING: linelist = stract ( (STRPTR) curstmt->stmt, noadtree, linelist ); break; case SPLINE: linelist = splact ( (EXPRPTR) curstmt->stmt, noadtree, linelist ); break; case OPAQUE: break; case BDLIST: break; case VAR: break; default: impossible ("rbuild"); } } return (linelist); } LINEPTR build (noadtree, linelist) NOADPTR noadtree; LINEPTR linelist; { LINEPTR retval; if (when_bug & 040) bug_on; retval = rbuild (noadtree, linelist); bug_off; return (retval); } LINEPTR connact (connstmt, noadtree, linelist) EXPRPTR connstmt; NOADPTR noadtree; LINEPTR linelist; { INTLPTR frompt, topt; LINEPTR newline; EXPRPTR linwalk; newline = NULL; frompt = expreval (connstmt->expr, noadtree); linwalk = connstmt->next; while (linwalk) { topt = expreval (linwalk->expr, noadtree); if (!known(frompt) || !known(topt)) { fprintf (stderr, "ideal: indeterminate endpoints\n >>>conn ignored\n"); } else { newline = linegen ( Re(frompt), Im(frompt), Re(topt), Im(topt) ); dprintf "Adding line (%f,%f) to (%f,%f)\n", Re(frompt), Im(frompt), Re(topt), Im(topt) ); newline->next = linelist; linelist = newline; } intlfree (frompt); frompt = topt; linwalk = linwalk->next; } intlfree (topt); return (newline); } LINEPTR penact (penstmt, noadtree, linelist) PENPTR penstmt; NOADPTR noadtree; LINEPTR linelist; { INTLPTR frompt, topt, copies; LINEPTR newline; frompt = expreval (penstmt->from, noadtree); topt = expreval (penstmt->to, noadtree); copies = expreval (penstmt->copies, noadtree); newline = linelist; if (!known(frompt) || !known(topt) || !known(copies)) { fprintf (stderr, "ideal: indeterminate pen\n >>>pen ignored\n"); } else { PUTNODE dummyput; NOADPTR pennoad; STMTPTR ostmthead; int i; dprintf "Drawing pen from (%f,%f) to (%f,%f)\n", Re(frompt), Im(frompt), Re(topt), Im(topt) ); /* add key statements to beginning of parameter section */ dummyput.name = 0; dummyput.parm = penstmt->pen; ostmthead = dummyput.parm->stmtlist; dummyput.parm->stmtlist = stmtgen ( '=', (char *) intlgen ( '=', (EXPR) extlgen (namegen (lookup ("$pencnt"))), (EXPR) fextlgen (0.0) ) ); dummyput.parm->stmtlist->next = stmtgen ( '=', (char *) intlgen ( '=', penstmt->start, bracket ( (EXPR) intlgen ( '/', (EXPR) extlgen(namegen(lookup("$pencnt"))), (EXPR) copies ), (EXPR) frompt, (EXPR) topt ) ) ); dummyput.parm->stmtlist->next->next = stmtgen ( '=', (char *) intlgen ( '=', penstmt->end, bracket ( (EXPR) intlgen ( '/', (EXPR) intlgen ( '+', (EXPR) extlgen(namegen(lookup("$pencnt"))), (EXPR) fextlgen(1.0) ), (EXPR) copies ), (EXPR) frompt, (EXPR) topt ) ) ); dummyput.parm->stmtlist->next->next->next = stmtgen ( VAR, (char *) namegen (lookup ("$pencnt")) ); dummyput.parm->stmtlist->next->next->next->next = ostmthead; /* make N copies */ for (i = 0; i < Re(copies); i ++) { ((EXTLPTR) ((INTLPTR) dummyput.parm->stmtlist->stmt)->right)->info.const = i; pennoad = buildnoadtree (&dummyput); pennoad->father = noadtree; eqneval (pennoad); nl_eval (); newline = build (pennoad, newline); depvarkill (); noadfree (pennoad); } if (dummyput.parm->stmtlist->next->next->next->next != ostmthead) impossible ("penact"); dummyput.parm->stmtlist->next->next->next->next = NULL; /* will have to let garbage collector get dummyput.parm */ penstmt->pen->stmtlist = ostmthead; } intlfree (frompt); intlfree (topt); intlfree (copies); return (newline); } LINEPTR drawact (noadname, noadtree, linelist) MISCPTR noadname; NOADPTR noadtree; LINEPTR linelist; { NOADPTR noadwalk; LINEPTR nuline; for (noadwalk = noadtree->son; noadwalk && (noadwalk->defnode->name != noadname->info); noadwalk = noadwalk->brother) dprintf "%s %s", idprint(noadwalk->defnode->name), idprint(noadname->info) ); ; if (noadwalk) { ((LINEPTR) tail ((BOXPTR) noadwalk->linelist))->next = linelist; nuline = noadwalk->linelist; noadwalk->linelist = NULL; return (nuline); } else { fprintf (stderr, "ideal: can't find %s to draw it\n", idprint (noadname->info) ); return (linelist); } } LINEPTR stract (strstmt, noadtree, linelist) STRPTR strstmt; NOADPTR noadtree; LINEPTR linelist; { LINEPTR newline; INTLPTR atpt; atpt = expreval (strstmt->at, noadtree); if (!known(atpt)){ fprintf (stderr, "ideal: indeterminate string location\n >>>string ignored\n"); newline = linelist; } else { dprintf "Adding string %s\n", strstmt->string); newline = textgen ( strstmt->command, strstmt->string, Re(atpt), Im(atpt) ); newline->next = linelist; } intlfree (atpt); return (newline); } LINEPTR circact (noadtree, linelist) NOADPTR noadtree; LINEPTR linelist; { LINEPTR newline; INTLPTR radius, center; radius = varfind (lookup ("radius"), noadtree); center = varfind (lookup ("center"), noadtree); if (!known(radius) || !known(center)) { fprintf (stderr, "ideal: indeterminate circle\n >>>ignored\n"); newline = linelist; } else { float rad; rad = Re(radius); dprintf "Adding circle %f %f %f\n", Re(center), Im(center), rad ); newline = circgen ( Re(center), Im(center), rad ); newline->next = linelist; } intlfree (radius); intlfree (center); return (newline); } LINEPTR arcact (noadtree, linelist) NOADPTR noadtree; LINEPTR linelist; { LINEPTR newline; INTLPTR start, center, end; INTLPTR temp; float radius; float startang, midang, endang; center = varfind (lookup ("center"), noadtree); start = varfind (lookup ("start"), noadtree); end = varfind (lookup ("end"), noadtree); temp = varfind (lookup ("startang"), noadtree); startang = Re(temp); tryfree(temp); temp = varfind (lookup ("midang"), noadtree); midang = Re(temp); tryfree(temp); temp = varfind (lookup ("endang"), noadtree); endang = Re(temp); tryfree(temp); if (!radflag) { dtor(startang); dtor(midang); dtor(endang); } startang = rprin (startang); midang = rprin (midang); endang = rprin (endang); if ((fabs(startang - midang) < EPSILON) && (startang > endang)) endang += 2*PI; radius = ((DEPPTR) (varfind (lookup ("radius"), noadtree))->left)->coeff; if (!known(center) || !known(start) || !known(end)) { fprintf (stderr, "ideal: indeterminate arc\n >>>ignored\n"); newline = linelist; } else { angorder (&startang, midang, &endang); dprintf "Adding arc %f %f %f %f %f\n", Re(center), Im(center), radius, startang, endang ); newline = angularc ( Re(center), Im(center), radius, startang, endang ); newline->next = linelist; } intlfree (center); intlfree (start); intlfree (end); return (newline); } LINEPTR splact (splstmt, noadtree, linelist) EXPRPTR splstmt; NOADPTR noadtree; LINEPTR linelist; { EXPRNODE knotlist; EXPRPTR knotwalk; EXPRPTR splwalk; LINEPTR nuline; if (when_bug & 0200) bug_on; knotwalk = &knotlist; knotwalk->next = NULL; for (splwalk = splstmt; splwalk; splwalk = splwalk->next ) { knotwalk->next = exprgen ( (EXPR) expreval ( splwalk->expr, noadtree ) ); if (!known(((INTLPTR) knotwalk->next->expr))) { fprintf (stderr, "ideal: unknown spline knot\n >>>spline ignored\n"); return (linelist); } knotwalk = knotwalk->next; dprintf "spline knot: %f %f\n", Re(((INTLPTR) knotwalk->expr)), Im(((INTLPTR) knotwalk->expr)) ); } nuline = splgen (knotlist.next); nuline->next = linelist; return (nuline); }