]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/pic/picy.y
stats: show amount of reclaimable pages (add -r flag)
[plan9front.git] / sys / src / cmd / pic / picy.y
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         ;