%{ #ifndef lint static char *yrcs = "$Header: xxx.y,v 1.2 88/02/03 08:52:12 simpson Exp $"; #endif /* $Log: xxx.y,v $ * Revision 1.2 88/02/03 08:52:12 simpson * added tpic support * * Revision 1.1 88/01/15 13:05:57 simpson * initial release * * Revision 0.1 87/12/11 18:31:27 simpson * beta test * */ #define TPICRES 1000 /* Tpic uses 1000 dots/inch */ static int Coordinates[300][2]; /* Coordinates used by tpic */ static int CoorCount; /* Count of # of coor in above array */ static int PenWidth; static int GraphOrigin[2]; static double Center[2], Cur[2], New[2]; static double CurvePts[300][3], SplinePts[500][3]; static enum {none, white, shade, black} Color; %} %union { int i; double f; char s[81]; } %token OVERLAY PENSIZE FLUSHPATH FLUSHDASHED FLUSHDOTTED ADDPATH DRAWARC %token FLUSHSPLINE SHADELAST WHITENLAST BLACKENLAST TEXTURE %token STRING %token INTEGER %token FLOAT %type validfile %% keywords : keyword ',' keywords | keyword | error ',' { yyerrok; } keywords ; keyword : OVERLAY '(' validfile { FILE *f; char filename[81], *expandtilde(), *strcpy(); int c; (void)strcpy(filename, $3); (void)expandtilde(filename); if (f = fopen(filename, "r")) { while ((c = getc(f)) != EOF) (void)putchar(c); (void)fclose(f); } } ')' | PENSIZE INTEGER { /* A pen command designates the start of a new graph */ PenWidth = ROUND($2 / 1000.0 * RESOLUTION); GraphOrigin[0] = Origin[0], GraphOrigin[1] = Origin[1]; CoorCount = 0; Color = none; } | FLUSHPATH { if (CoorCount > 1) { int i; fputs(VECTORON, stdout); printf("%s%05d:%05d", PENUP, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); printf("%s%02d", PENWIDTH, PenWidth); for (i = 1; i < CoorCount; i++) printf("%s%05d:%05d", PENDOWN, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); fputs(VECTOROFF, stdout); } if (CoorCount >=4 && Color != none) { /* Find midpoint of diagonal */ Center[0] = ((GraphOrigin[0]/(double)RESOLUTION+ Coordinates[0][0]/(double)TPICRES)+(GraphOrigin[0]/ (double)RESOLUTION+Coordinates[2][0]/(double)TPICRES))/2.0; Center[1] = ((GraphOrigin[1]/(double)RESOLUTION+ Coordinates[0][1]/(double)TPICRES)+(GraphOrigin[1]/ (double)RESOLUTION+Coordinates[2][1]/(double)TPICRES))/2.0; printf("%s%05d%05d", AREAFILL, ROUND(Center[0]*1000),ROUND(Center[1]*1000)); switch (Color) { case white: printf("%02d", 0); break; case shade: printf("%02d", 19); break; case black: printf("%02d", 20); break; } printf("%s", ENDCMD); } CoorCount = 0; Color = none; } | FLUSHDASHED FLOAT { if (CoorCount > 1) { int i; fputs(VECTORON, stdout); printf("%s%05d:%05d", PENUP, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); printf("%s%02d", PENWIDTH, PenWidth); printf("%s%d", "^V", 4); for (i = 1; i < CoorCount; i++) printf("%s%05d:%05d", PENDOWN, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); fputs(VECTOROFF, stdout); } CoorCount = 0; Color = none; } | FLUSHDOTTED FLOAT { if (CoorCount > 1) { int i; fputs(VECTORON, stdout); printf("%s%05d:%05d", PENUP, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[0][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[0][1]/(double)TPICRES)*1000)); printf("%s%02d", PENWIDTH, PenWidth); printf("%s%d", "^V", 2); for (i = 1; i < CoorCount; i++) printf("%s%05d:%05d", PENDOWN, ROUND((GraphOrigin[0]/(double)RESOLUTION+Coordinates[i][0]/(double)TPICRES)*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+Coordinates[i][1]/(double)TPICRES)*1000)); fputs(VECTOROFF, stdout); } CoorCount = 0; Color = none; } | ADDPATH INTEGER INTEGER { Coordinates[CoorCount][0] = $2, Coordinates[CoorCount++][1] = $3; } | DRAWARC INTEGER INTEGER INTEGER INTEGER FLOAT FLOAT { Center[0] = GraphOrigin[0] / (double)RESOLUTION + $2 / (double)TPICRES, Center[1] = GraphOrigin[1] / (double)RESOLUTION + $3 / (double)TPICRES; if ($4 != $5) { /* Ellipse */ int i; /* Ellipses satisfy the equation (x^2)/(a^2)+(y^2)/(b^2)=1 * where 'a' is the length of the semimajor axis and 'b' * is the length of the semiminor axis. We divide each * quadrant into 200 line segments and connect the line * segments. */ /* Cur and New are relative to the origin */ Cur[0] = $4 / (double)TPICRES, Cur[1] = 0.0; fputs(VECTORON, stdout); printf("%s%02d", PENWIDTH, PenWidth); for (i = 1; i <= 200; i++, Cur[0] = New[0], Cur[1] = New[1]) { New[0] = ($4/(double)TPICRES)*cos((i/200.0)*(PI/2.0)), New[1] = ($5/(double)TPICRES)*sin((i/200.0)*(PI/2.0)); /* First quadrant */ printf("%s%05d:%05d", PENUP, ROUND((Center[0]+Cur[0])*1000.0), ROUND((Center[1]+Cur[1])*1000.0)); printf("%s%05d:%05d", PENDOWN, ROUND((Center[0]+New[0])*1000.0), ROUND((Center[1]+New[1])*1000.0)); /* Second quadrant */ printf("%s%05d:%05d", PENUP, ROUND((Center[0]-Cur[0])*1000.0), ROUND((Center[1]+Cur[1])*1000.0)); printf("%s%05d:%05d", PENDOWN, ROUND((Center[0]-New[0])*1000.0), ROUND((Center[1]+New[1])*1000.0)); /* Third quadrant */ printf("%s%05d:%05d", PENUP, ROUND((Center[0]-Cur[0])*1000.0), ROUND((Center[1]-Cur[1])*1000.0)); printf("%s%05d:%05d", PENDOWN, ROUND((Center[0]-New[0])*1000.0), ROUND((Center[1]-New[1])*1000.0)); /* Fourth quadrant */ printf("%s%05d:%05d", PENUP, ROUND((Center[0]+Cur[0])*1000.0), ROUND((Center[1]-Cur[1])*1000.0)); printf("%s%05d:%05d", PENDOWN, ROUND((Center[0]+New[0])*1000.0), ROUND((Center[1]-New[1])*1000.0)); if (Color != none) { printf("%s%05d%05d", AREAFILL, ROUND(Center[0]*1000),ROUND(Center[1]*1000)); switch (Color) { case white: printf("%02d", 0); break; case shade: printf("%02d", 19); break; case black: printf("%02d", 20); break; } printf("%s", ENDCMD); Color = none; } } fputs(VECTOROFF, stdout); } else { /* Arc */ printf("%s%c%05d%c%05d%05d%03d%03d%02d%s", DECIMALARC, Center[0]>0?'+':'-', Center[0]>0?ROUND(Center[0]*1000): ROUND(-Center[0]*1000),Center[1]>0?'+':'-', Center[1]>0?ROUND(Center[1]*1000): ROUND(-Center[1]*1000),$4,ROUND($6/PI*500.0)>999?999: ROUND($6/PI*500.0),ROUND($7/PI*500.0)>999?999: ROUND($7/PI*500.0), PenWidth, ENDCMD); if ($6 == 0 && ABS($7-2*PI) < 0.01) if (Color != none) { printf("%s%05d%05d", AREAFILL, ROUND(Center[0]*1000),ROUND(Center[1]*1000)); switch (Color) { case white: printf("%02d", 0); break; case shade: printf("%02d", 19); break; case black: printf("%02d", 20); break; } printf("%s", ENDCMD); Color = none; } } } | FLUSHSPLINE { if (CoorCount > 1) { int i; for (i = 0; i < CoorCount; i++) { CurvePts[i][0] = Coordinates[i][0] / (double)TPICRES; CurvePts[i][1] = Coordinates[i][1] / (double)TPICRES; CurvePts[i][2] = 0.0; /* z-axis not used */ } spline(CurvePts,CoorCount-1,SplinePts,499,3); /* 2nd degree */ fputs(VECTORON, stdout); printf("%s%05d:%05d", PENUP, ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[0][0])*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[0][1])*1000)); printf("%s%02d", PENWIDTH, PenWidth); for (i = 1; i < 500; i++) printf("%s%05d:%05d", PENDOWN, ROUND((GraphOrigin[0]/(double)RESOLUTION+SplinePts[i][0])*1000), ROUND((GraphOrigin[1]/(double)RESOLUTION+SplinePts[i][1])*1000)); fputs(VECTOROFF, stdout); } CoorCount = 0; } | TEXTURE textureargs /* Ignore - Imagen only */ | SHADELAST { Color = shade; } | WHITENLAST { Color = white; } | BLACKENLAST { Color = black; } ; validfile : STRING { (void)strcpy($$, $1); } | OVERLAY { (void)strcpy($$, "overlay"); } | PENSIZE { (void)strcpy($$, "pn"); } | FLUSHPATH { (void)strcpy($$, "fp"); } | FLUSHDASHED { (void)strcpy($$, "da"); } | FLUSHDOTTED { (void)strcpy($$, "dt"); } | ADDPATH { (void)strcpy($$, "pa"); } | DRAWARC { (void)strcpy($$, "ar"); } | FLUSHSPLINE { (void)strcpy($$, "sp"); } | SHADELAST { (void)strcpy($$, "sh"); } | WHITENLAST { (void)strcpy($$, "wh"); } | BLACKENLAST { (void)strcpy($$, "bk"); } | TEXTURE { (void)strcpy($$, "tx"); } | INTEGER { (void)sprintf($$, "%d", $1); } /* | Unfortunately this won't work since the lexeme FLOAT of a float has been lost when we converted it to a { real number. (void)sprintf($$, "%f", $1); } */ ; textureargs : texturearg textureargs | /* epsilon */ ; texturearg : STRING | INTEGER ; %% #include "xxxlex.c" yyerror(s) char *s; { return; }