plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

picy.y (9415B)


      1 %{
      2 #include <stdio.h>
      3 #include "pic.h"
      4 #include <math.h>
      5 #include <stdlib.h>
      6 #include <string.h>
      7 
      8 YYSTYPE	y;
      9 
     10 extern	void	yyerror(char *);
     11 extern	int	yylex(void);
     12 %}
     13 
     14 %token	<i>	BOX	1	/* DON'T CHANGE THESE! */
     15 %token	<i>	LINE	2
     16 %token	<i>	ARROW	3
     17 %token	<i>	CIRCLE	4
     18 %token	<i>	ELLIPSE	5
     19 %token	<i>	ARC	6
     20 %token	<i>	SPLINE	7
     21 %token	<i>	BLOCK	8
     22 %token	<p>	TEXT	9
     23 %token	<p>	TROFF	10
     24 %token	<i>	MOVE	11
     25 %token	<i>	BLOCKEND 12
     26 %token	<i>	PLACE	13
     27 %token	<i>	PRINT RESET THRU UNTIL
     28 %token	<o>	FOR IF COPY
     29 %token	<p>	THENSTR ELSESTR DOSTR PLACENAME VARNAME SPRINTF
     30 %token	<st>	DEFNAME
     31 %token	<i>	ATTR TEXTATTR
     32 %token	<i>	LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN
     33 %token	<i>	HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE
     34 %token	<i>	CORNER HERE LAST NTH SAME BETWEEN AND
     35 %token	<i>	EAST WEST NORTH SOUTH NE NW SE SW START END
     36 %token	<i>	DOTX DOTY DOTHT DOTWID DOTRAD
     37 %token	<f>	NUMBER
     38 %token	<f>	LOG EXP SIN COS ATAN2 SQRT RAND MIN MAX INT
     39 %token	<i>	DIR
     40 %token	<i>	DOT DASH CHOP FILL NOEDGE
     41 %token	<o>	ST	/* statement terminator */
     42 
     43 %right	<f>	'='
     44 %left	<f>	OROR
     45 %left	<f>	ANDAND
     46 %nonassoc <f>	GT LT LE GE EQ NEQ
     47 %left	<f>	'+' '-'
     48 %left	<f>	'*' '/' '%'
     49 %right	<f>	UMINUS NOT
     50 %right	<f>	'^'
     51 
     52 %type	<f>	expr if_expr asgn
     53 %type	<p>	name text
     54 %type	<i>	optop exprlist
     55 %type	<o>	if for copy
     56 
     57 /* this is a lie:  picture and position are really the whole union */
     58 %type	<o>	leftbrace picture piclist position lbracket
     59 %type	<o>	prim place blockname
     60 %type	<i>	textlist textattr	/* not a sensible value */
     61 %type	<i>	last type
     62 
     63 %%
     64 
     65 top:
     66 	  piclist
     67 	| /* empty */
     68 	| error		{ ERROR "syntax error" WARNING; }
     69 	;
     70 
     71 piclist:
     72 	  picture
     73 	| piclist picture
     74 	;
     75 
     76 picture:
     77 	  prim ST			{ codegen = 1; makeiattr(0, 0); }
     78 	| leftbrace piclist '}'		{ rightthing($1, '}'); $$ = $2; }
     79 	| PLACENAME ':' picture		{ y.o=$3; makevar($1,PLACENAME,y); $$ = $3; }
     80 	| PLACENAME ':' ST picture	{ y.o=$4; makevar($1,PLACENAME,y); $$ = $4; }
     81 	| PLACENAME ':' position ST	{ y.o=$3; makevar($1,PLACENAME,y); $$ = $3; }
     82 	| asgn ST			{ y.f = $1; $$ = y.o; $$ = makenode(PLACE, 0); }
     83 	| DIR				{ setdir($1); $$ = makenode(PLACE, 0); }
     84 	| PRINT expr ST			{ printexpr($2); $$ = makenode(PLACE, 0); }
     85 	| PRINT position ST		{ printpos($2); $$ = makenode(PLACE, 0); }
     86 	| PRINT text ST			{ printf("%s\n", $2); free($2); $$ = makenode(PLACE, 0); }
     87 	| RESET varlist ST		{ resetvar(); makeiattr(0, 0); $$ = makenode(PLACE, 0); }
     88 	| copy
     89 	| for
     90 	| if
     91 	| ST
     92 	;
     93 
     94 varlist:
     95 	  /* empty */
     96 	| VARNAME		{ makevattr($1); }
     97 	| varlist VARNAME	{ makevattr($2); }
     98 	| varlist ',' VARNAME	{ makevattr($3); }
     99 	;
    100 
    101 asgn:
    102 	  VARNAME '=' expr	{ $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); }
    103 	;
    104 
    105 copy:
    106 	  COPY copylist		{ copy(); }
    107 	;
    108 copylist:
    109 	  copyattr
    110 	| copylist copyattr
    111 	;
    112 copyattr:
    113 	  text			{ copyfile($1); }
    114 	| THRU DEFNAME		{ copydef($2); }
    115 	| UNTIL text		{ copyuntil($2); }
    116 	;
    117 
    118 for:
    119 	  FOR name FROM expr TO expr BY optop expr DOSTR
    120 		{ forloop($2, $4, $6, $8, $9, $10); }
    121 	| FOR name FROM expr TO expr DOSTR
    122 		{ forloop($2, $4, $6, '+', 1.0, $7); }
    123 	| FOR name '=' expr TO expr BY optop expr DOSTR
    124 		{ forloop($2, $4, $6, $8, $9, $10); }
    125 	| FOR name '=' expr TO expr DOSTR
    126 		{ forloop($2, $4, $6, '+', 1.0, $7); }
    127 	;
    128 
    129 if:
    130 	  IF if_expr THENSTR ELSESTR	{ ifstat($2, $3, $4); }
    131 	| IF if_expr THENSTR		{ ifstat($2, $3, (char *) 0); }
    132 	;
    133 if_expr:
    134 	  expr
    135 	| text EQ text		{ $$ = strcmp($1,$3) == 0; free($1); free($3); }
    136 	| text NEQ text		{ $$ = strcmp($1,$3) != 0; free($1); free($3); }
    137 	;
    138 
    139 name:
    140 	  VARNAME	{ y.f = 0; makevar($1, VARNAME, y); }
    141 	;
    142 optop:
    143 	  '+'		{ $$ = '+'; }
    144 	| '-'		{ $$ = '-'; }
    145 	| '*'		{ $$ = '*'; }
    146 	| '/'		{ $$ = '/'; }
    147 	| /* empty */	{ $$ = ' '; }
    148 	;
    149 
    150 
    151 leftbrace:
    152 	  '{'			{ $$ = leftthing('{'); }
    153 	;
    154 
    155 prim:
    156 	  BOX attrlist		{ $$ = boxgen(); }
    157 	| CIRCLE attrlist	{ $$ = circgen($1); }
    158 	| ELLIPSE attrlist	{ $$ = circgen($1); }
    159 	| ARC attrlist		{ $$ = arcgen($1); }
    160 	| LINE attrlist		{ $$ = linegen($1); }
    161 	| ARROW attrlist	{ $$ = linegen($1); }
    162 	| SPLINE attrlist	{ $$ = linegen($1); }
    163 	| MOVE attrlist		{ $$ = movegen(); }
    164 	| textlist attrlist	{ $$ = textgen(); }
    165 	| TROFF			{ $$ = troffgen($1); }
    166 	| lbracket piclist ']' { $<o>$=rightthing($1,']'); } attrlist
    167 				{ $$ = blockgen($1, $<o>4); }
    168 	;
    169 
    170 lbracket:
    171 	  '['			{ $$ = leftthing('['); }
    172 	;
    173 
    174 attrlist:
    175 	  attrlist attr
    176 	| /* empty */
    177 	;
    178 
    179 attr:
    180 	  ATTR expr		{ makefattr($1, !DEFAULT, $2); }
    181 	| ATTR			{ makefattr($1, DEFAULT, 0.0); }
    182 	| expr			{ makefattr(curdir(), !DEFAULT, $1); }
    183 	| DIR expr		{ makefattr($1, !DEFAULT, $2); }
    184 	| DIR			{ makefattr($1, DEFAULT, 0.0); }
    185 	| FROM position		{ makeoattr($1, $2); }
    186 	| TO position		{ makeoattr($1, $2); }
    187 	| AT position		{ makeoattr($1, $2); }
    188 	| BY position		{ makeoattr($1, $2); }
    189 	| WITH CORNER		{ makeiattr(WITH, $2); }
    190 	| WITH '.' PLACENAME	{ makeoattr(PLACE, getblock(getlast(1,BLOCK), $3)); }
    191 	| WITH '.' PLACENAME CORNER
    192 		{ makeoattr(PLACE, getpos(getblock(getlast(1,BLOCK), $3), $4)); }
    193 	| WITH position		{ makeoattr(PLACE, $2); }
    194 	| SAME			{ makeiattr(SAME, $1); }
    195 	| TEXTATTR		{ maketattr($1, (char *) 0); }
    196 	| HEAD			{ makeiattr(HEAD, $1); }
    197 	| DOT expr		{ makefattr(DOT, !DEFAULT, $2); }
    198 	| DOT			{ makefattr(DOT, DEFAULT, 0.0); }
    199 	| DASH expr		{ makefattr(DASH, !DEFAULT, $2); }
    200 	| DASH			{ makefattr(DASH, DEFAULT, 0.0); }
    201 	| CHOP expr		{ makefattr(CHOP, !DEFAULT, $2); }
    202 	| CHOP			{ makefattr(CHOP, DEFAULT, 0.0); }
    203 	| CHOP PLACENAME	{ makeattr(CHOP, PLACENAME, getvar($2)); }
    204 	| FILL expr		{ makefattr(FILL, !DEFAULT, $2); }
    205 	| FILL			{ makefattr(FILL, DEFAULT, 0.0); }
    206 	| NOEDGE		{ makeiattr(NOEDGE, 0); }
    207 	| textlist
    208 	;
    209 
    210 textlist:
    211 	  textattr
    212 	| textlist textattr
    213 	;
    214 textattr:
    215 	  text			{ maketattr(CENTER, $1); }
    216 	| text TEXTATTR		{ maketattr($2, $1); }
    217 	| textattr TEXTATTR	{ addtattr($2); }
    218 	;
    219 text:
    220 	  TEXT
    221 	| SPRINTF '(' text ')'			{ $$ = sprintgen($3); }
    222 	| SPRINTF '(' text ',' exprlist ')'	{ $$ = sprintgen($3); }
    223 	;
    224 
    225 exprlist:
    226 	  expr			{ exprsave($1); $$ = 0; }
    227 	| exprlist ',' expr	{ exprsave($3); }
    228 	;
    229 
    230 position:		/* absolute, not relative */
    231 	  place
    232 	| '(' position ')'			{ $$ = $2; }
    233 	| expr ',' expr				{ $$ = makepos($1, $3); }
    234 	| position '+' expr ',' expr		{ $$ = fixpos($1, $3, $5); }
    235 	| position '-' expr ',' expr		{ $$ = fixpos($1, -$3, -$5); }
    236 	| position '+' '(' expr ',' expr ')'	{ $$ = fixpos($1, $4, $6); }
    237 	| position '-' '(' expr ',' expr ')'	{ $$ = fixpos($1, -$4, -$6); }
    238 	| position '+' place			{ $$ = addpos($1, $3); }
    239 	| position '-' place			{ $$ = subpos($1, $3); }
    240 	| '(' place ',' place ')'	{ $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); }
    241 	| expr LT position ',' position GT	{ $$ = makebetween($1, $3, $5); }
    242 	| expr BETWEEN position AND position	{ $$ = makebetween($1, $3, $5); }
    243 	;
    244 
    245 place:
    246 	  PLACENAME		{ y = getvar($1); $$ = y.o; }
    247 	| PLACENAME CORNER	{ y = getvar($1); $$ = getpos(y.o, $2); }
    248 	| CORNER PLACENAME	{ y = getvar($2); $$ = getpos(y.o, $1); }
    249 	| HERE			{ $$ = gethere(); }
    250 	| last type		{ $$ = getlast($1, $2); }
    251 	| last type CORNER	{ $$ = getpos(getlast($1, $2), $3); }
    252 	| CORNER last type	{ $$ = getpos(getlast($2, $3), $1); }
    253 	| NTH type		{ $$ = getfirst($1, $2); }
    254 	| NTH type CORNER	{ $$ = getpos(getfirst($1, $2), $3); }
    255 	| CORNER NTH type	{ $$ = getpos(getfirst($2, $3), $1); }
    256 	| blockname
    257 	| blockname CORNER	{ $$ = getpos($1, $2); }
    258 	| CORNER blockname	{ $$ = getpos($2, $1); }
    259 	;
    260 
    261 blockname:
    262 	  last BLOCK '.' PLACENAME	{ $$ = getblock(getlast($1,$2), $4); }
    263 	| NTH BLOCK '.' PLACENAME	{ $$ = getblock(getfirst($1,$2), $4); }
    264 	| PLACENAME '.' PLACENAME	{ y = getvar($1); $$ = getblock(y.o, $3); }
    265 	;
    266 
    267 last:
    268 	  last LAST		{ $$ = $1 + 1; }
    269 	| NTH LAST		{ $$ = $1; }
    270 	| LAST			{ $$ = 1; }
    271 	;
    272 
    273 type:
    274 	  BOX
    275 	| CIRCLE
    276 	| ELLIPSE
    277 	| ARC
    278 	| LINE
    279 	| ARROW
    280 	| SPLINE
    281 	| BLOCK
    282 	;
    283 
    284 expr:
    285 	  NUMBER
    286 	| VARNAME		{ $$ = getfval($1); }
    287 	| asgn
    288 	| expr '+' expr		{ $$ = $1 + $3; }
    289 	| expr '-' expr		{ $$ = $1 - $3; }
    290 	| expr '*' expr		{ $$ = $1 * $3; }
    291 	| expr '/' expr		{ if ($3 == 0.0) {
    292 					ERROR "division by 0" WARNING; $3 = 1; }
    293 				  $$ = $1 / $3; }
    294 	| expr '%' expr		{ if ((long)$3 == 0) {
    295 					ERROR "mod division by 0" WARNING; $3 = 1; }
    296 				  $$ = (long)$1 % (long)$3; }
    297 	| '-' expr %prec UMINUS	{ $$ = -$2; }
    298 	| '+' expr %prec UMINUS	{ $$ = $2; }
    299 	| '(' expr ')'		{ $$ = $2; }
    300 	| place DOTX		{ $$ = getcomp($1, $2); }
    301 	| place DOTY		{ $$ = getcomp($1, $2); }
    302 	| place DOTHT		{ $$ = getcomp($1, $2); }
    303 	| place DOTWID		{ $$ = getcomp($1, $2); }
    304 	| place DOTRAD		{ $$ = getcomp($1, $2); }
    305 	| PLACENAME '.' VARNAME	{ y = getvar($1); $$ = getblkvar(y.o, $3); }
    306 	| last BLOCK '.' VARNAME { $$ = getblkvar(getlast($1,$2), $4); }
    307 	| NTH BLOCK '.' VARNAME	{ $$ = getblkvar(getfirst($1,$2), $4); }
    308 	| expr GT expr		{ $$ = $1 > $3; }
    309 	| expr LT expr		{ $$ = $1 < $3; }
    310 	| expr LE expr		{ $$ = $1 <= $3; }
    311 	| expr GE expr		{ $$ = $1 >= $3; }
    312 	| expr EQ expr		{ $$ = $1 == $3; }
    313 	| expr NEQ expr		{ $$ = $1 != $3; }
    314 	| expr ANDAND expr	{ $$ = $1 && $3; }
    315 	| expr OROR expr	{ $$ = $1 || $3; }
    316 	| NOT expr		{ $$ = !($2); }
    317 	| LOG '(' expr ')'		{ $$ = Log10($3); }
    318 	| EXP '(' expr ')'		{ $$ = Exp($3 * log(10.0)); }
    319 	| expr '^' expr			{ $$ = pow($1, $3); }
    320 	| SIN '(' expr ')'		{ $$ = sin($3); }
    321 	| COS '(' expr ')'		{ $$ = cos($3); }
    322 	| ATAN2 '(' expr ',' expr ')'	{ $$ = atan2($3, $5); }
    323 	| SQRT '(' expr ')'		{ $$ = Sqrt($3); }
    324 	| RAND '(' ')'			{ $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ }
    325 	| MAX '(' expr ',' expr ')'	{ $$ = $3 >= $5 ? $3 : $5; }
    326 	| MIN '(' expr ',' expr ')'	{ $$ = $3 <= $5 ? $3 : $5; }
    327 	| INT '(' expr ')'		{ $$ = (long) $3; }
    328 	;