]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/grap/grap.y
aux/realemu: run cpuproc in same fd group as fileserver
[plan9front.git] / sys / src / cmd / grap / grap.y
1 %{
2 #include <stdio.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "grap.h"
7
8 #define RAND_MAX 32767  /* if your rand() returns bigger, change this too */
9
10 extern int yylex(void);
11 extern int yyparse(void);
12
13 %}
14
15 %token  <i>     FRAME TICKS GRID LABEL COORD
16 %token  <i>     LINE ARROW CIRCLE DRAW NEW PLOT NEXT
17 %token  <p>     PIC
18 %token  <i>     COPY THRU UNTIL
19 %token  <i>     FOR FROM TO BY AT WITH
20 %token  <i>     IF
21 %token  <p>     GRAPH THEN ELSE DOSTR
22 %token  <i>     DOT DASH INVIS SOLID
23 %token  <i>     TEXT JUST SIZE
24 %token  <i>     LOG EXP SIN COS ATAN2 SQRT RAND MAX MIN INT PRINT SPRINTF
25 %token  <i>     X Y SIDE IN OUT OFF UP DOWN ACROSS
26 %token  <i>     HEIGHT WIDTH RADIUS
27 %token  <f>     NUMBER
28 %token  <op>    NAME VARNAME DEFNAME
29 %token  <p>     STRING
30 %token  <i>     ST '(' ')' ','
31
32 %right  <f>     '='
33 %left   <f>     OR
34 %left   <f>     AND
35 %nonassoc <f>   GT LT LE GE EQ NE
36 %left   <f>     '+' '-'
37 %left   <f>     '*' '/' '%'
38 %right  <f>     UMINUS NOT
39 %right  <f>     '^'
40
41 %type   <f>     expr optexpr if_expr number assign
42 %type   <i>     optop
43 %type   <p>     optstring if
44 %type   <op>    optname iterator name
45 %type   <pt>    point
46 %type   <i>     side optside numlist comma linetype drawtype
47 %type   <ap>    linedesc optdesc stringlist string stringattr sattrlist exprlist
48 %type   <i>     frameitem framelist coordlog
49 %type   <f>     string_expr
50
51 %%
52
53 top:
54           graphseq              { if (codegen && !synerr) graph((char *) 0); }
55         | /* empty */           { codegen = 0; }
56         | error                 { codegen = 0; ERROR "syntax error" WARNING; }
57         ;
58
59 graphseq:
60           statlist
61         | graph statlist
62         | graphseq graph statlist
63         ;
64 graph:
65           GRAPH                 { graph($1); endstat(); }
66         ;
67
68 statlist:
69           ST
70         | stat ST               { endstat(); }
71         | statlist stat ST      { endstat(); }
72         ;
73
74 stat:
75           FRAME framelist       { codegen = 1; }
76         | ticks                 { codegen = 1; }
77         | grid                  { codegen = 1; }
78         | label                 { codegen = 1; }
79         | coord
80         | plot                  { codegen = 1; }
81         | line                  { codegen = 1; }
82         | circle                { codegen = 1; }
83         | draw
84         | next                  { codegen = 1; }
85         | PIC                   { codegen = 1; pic($1); }
86         | for
87         | if
88         | copy
89         | numlist               { codegen = 1; numlist(); }
90         | assign
91         | PRINT expr            { fprintf(stderr, "\t%g\n", $2); }
92         | PRINT string          { fprintf(stderr, "\t%s\n", $2->sval); freeattr($2); }
93         | /* empty */
94         ;
95
96 numlist:
97           number                { savenum(0, $1); $$ = 1; }
98         | numlist number        { savenum($1, $2); $$ = $1+1; }
99         | numlist comma number  { savenum($1, $3); $$ = $1+1; }
100         ;
101 number:
102           NUMBER
103         | '-' NUMBER %prec UMINUS       { $$ = -$2; }
104         | '+' NUMBER %prec UMINUS       { $$ = $2; }
105         ;
106
107 label:
108           LABEL optside stringlist lablist      { label($2, $3); }
109         ;
110 lablist:
111           labattr
112         | lablist labattr
113         | /* empty */
114         ;
115 labattr:
116           UP expr               { labelmove($1, $2); }
117         | DOWN expr             { labelmove($1, $2); }
118         | SIDE expr             { labelmove($1, $2); /* LEFT or RIGHT only */ }
119         | WIDTH expr            { labelwid($2); }
120         ;
121
122 framelist:
123           framelist frameitem
124         | /* empty */           { $$ = 0; }
125         ;
126 frameitem:
127           HEIGHT expr           { frameht($2); }
128         | WIDTH expr            { framewid($2); }
129         | side linedesc         { frameside($1, $2); }
130         | linedesc              { frameside(0, $1); }
131         ;
132 side:
133           SIDE
134         ;
135 optside:
136           side
137         | /* empty */           { $$ = 0; }
138         ;
139
140 linedesc:
141           linetype optexpr      { $$ = makeattr($1, $2, (char *) 0, 0, 0); }
142         ;
143 linetype:
144           DOT | DASH | SOLID | INVIS
145         ;
146 optdesc:
147           linedesc
148         | /* empty */           { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); }
149         ;
150
151 ticks:
152           TICKS tickdesc        { ticks(); }
153         ;
154 tickdesc:
155           tickattr
156         | tickdesc tickattr
157         ;
158 tickattr:
159           side                  { tickside($1); }
160         | IN expr               { tickdir(IN, $2, 1); }
161         | OUT expr              { tickdir(OUT, $2, 1); }
162         | IN                    { tickdir(IN, 0.0, 0); }
163         | OUT                   { tickdir(OUT, 0.0, 0); }
164         | AT optname ticklist   { setlist(); ticklist($2, AT); }
165         | iterator              { setlist(); ticklist($1, AT); }
166         | side OFF              { tickoff($1); }
167         | OFF                   { tickoff(LEFT|RIGHT|TOP|BOT); }
168         | labattr
169         ;
170 ticklist:
171           tickpoint
172         | ticklist comma tickpoint
173         ;
174 tickpoint:
175           expr                  { savetick($1, (char *) 0); }
176         | expr string           { savetick($1, $2->sval); }
177         ;
178 iterator:
179           FROM optname expr TO optname expr BY optop expr optstring
180                         { iterator($3, $6, $8, $9, $10); $$ = $2; }
181         | FROM optname expr TO optname expr optstring
182                         { iterator($3, $6, '+', 1.0, $7); $$ = $2; }
183         ;
184 optop:
185           '+'           { $$ = '+'; }
186         | '-'           { $$ = '-'; }
187         | '*'           { $$ = '*'; }
188         | '/'           { $$ = '/'; }
189         | /* empty */   { $$ = ' '; }
190         ;
191 optstring:
192           string        { $$ = $1->sval; }
193         | /* empty */   { $$ = (char *) 0; }
194         ;
195
196 grid:
197           GRID griddesc         { ticks(); }
198         ;
199 griddesc:
200           gridattr
201         | griddesc gridattr
202         ;
203 gridattr:
204           side                  { tickside($1); }
205         | X                     { tickside(BOT); }
206         | Y                     { tickside(LEFT); }
207         | linedesc              { griddesc($1); }
208         | AT optname ticklist   { setlist(); gridlist($2); }
209         | iterator              { setlist(); gridlist($1); }
210         | TICKS OFF             { gridtickoff(); }
211         | OFF                   { gridtickoff(); }
212         | labattr
213         ;
214
215 line:
216           LINE FROM point TO point optdesc      { line($1, $3, $5, $6); }
217         | LINE optdesc FROM point TO point      { line($1, $4, $6, $2); }
218         ;
219 circle:
220           CIRCLE RADIUS expr AT point           { circle($3, $5); }
221         | CIRCLE AT point RADIUS expr           { circle($5, $3); }
222         | CIRCLE AT point                       { circle(0.0, $3); }
223         ;
224
225 stringlist:
226           string
227         | stringlist string     { $$ = addattr($1, $2); }
228         ;
229 string:
230           STRING sattrlist      { $$ = makesattr($1); }
231         | SPRINTF '(' STRING ')' sattrlist
232                                 { $$ = makesattr(sprntf($3, (Attr*) 0)); }
233         | SPRINTF '(' STRING ',' exprlist ')' sattrlist
234                                 { $$ = makesattr(sprntf($3, $5)); }
235         ;
236 exprlist:
237           expr                  { $$ = makefattr(NUMBER, $1); }
238         | exprlist ',' expr     { $$ = addattr($1, makefattr(NUMBER, $3)); }
239         ;
240 sattrlist:
241           stringattr
242         | sattrlist stringattr
243         | /* empty */           { $$ = (Attr *) 0; }
244         ;
245 stringattr:
246           JUST                  { setjust($1); }
247         | SIZE optop expr       { setsize($2, $3); }
248         ;
249
250 coord:
251           COORD optname coordlist       { coord($2); }
252         | COORD optname                 { resetcoord($2); }
253         ;
254 coordlist:
255           coorditem
256         | coordlist coorditem
257         ;
258 coorditem:
259           coordlog      { coordlog($1); }
260         | X point       { coord_x($2); }
261         | Y point       { coord_y($2); }
262         | X optname expr TO expr                { coord_x(makepoint($2, $3, $5)); }
263         | Y optname expr TO expr                { coord_y(makepoint($2, $3, $5)); }
264         | X FROM optname expr TO expr           { coord_x(makepoint($3, $4, $6)); }
265         | Y FROM optname expr TO expr           { coord_y(makepoint($3, $4, $6)); }
266         ;
267 coordlog:
268           LOG X         { $$ = XFLAG; }
269         | LOG Y         { $$ = YFLAG; }
270         | LOG X LOG Y   { $$ = XFLAG|YFLAG; }
271         | LOG Y LOG X   { $$ = XFLAG|YFLAG; }
272         | LOG LOG       { $$ = XFLAG|YFLAG; }
273         ;
274
275 plot:
276           stringlist AT point           { plot($1, $3); }
277         | PLOT stringlist AT point      { plot($2, $4); }
278         | PLOT expr optstring AT point  { plotnum($2, $3, $5); }
279         ;
280
281 draw:
282           drawtype optname linedesc             { drawdesc($1, $2, $3, (char *) 0); }
283         | drawtype optname optdesc string       { drawdesc($1, $2, $3, $4->sval); }
284         | drawtype optname string optdesc       { drawdesc($1, $2, $4, $3->sval); }
285         ;
286 drawtype:
287           DRAW
288         | NEW
289         ;
290
291 next:
292           NEXT optname AT point optdesc         { next($2, $4, $5); }
293
294 copy:
295           COPY copylist         { copy(); }
296         ;
297 copylist:
298           copyattr
299         | copylist copyattr
300         ;
301 copyattr:
302           string                { copyfile($1->sval); }
303         | THRU DEFNAME          { copydef($2); }
304         | UNTIL string          { copyuntil($2->sval); }
305         ;
306
307 for:
308           FOR name FROM expr TO expr BY optop expr DOSTR
309                 { forloop($2, $4, $6, $8, $9, $10); }
310         | FOR name FROM expr TO expr DOSTR
311                 { forloop($2, $4, $6, '+', 1.0, $7); }
312         | FOR name '=' expr TO expr BY optop expr DOSTR
313                 { forloop($2, $4, $6, $8, $9, $10); }
314         | FOR name '=' expr TO expr DOSTR
315                 { forloop($2, $4, $6, '+', 1.0, $7); }
316         ;
317
318 if:
319           IF if_expr THEN ELSE          { $$ = ifstat($2, $3, $4); }
320         | IF if_expr THEN               { $$ = ifstat($2, $3, (char *) 0); }
321         ;
322 if_expr:
323           expr
324         | string_expr
325         | if_expr AND string_expr       { $$ = $1 && $3; }
326         | if_expr OR string_expr        { $$ = $1 || $3; }
327         ;
328 string_expr:
329           STRING EQ STRING      { $$ = strcmp($1,$3) == 0; free($1); free($3); }
330         | STRING NE STRING      { $$ = strcmp($1,$3) != 0; free($1); free($3); }
331         ;
332
333 point:
334           optname expr comma expr               { $$ = makepoint($1, $2, $4); }
335         | optname '(' expr comma expr ')'       { $$ = makepoint($1, $3, $5); }
336         ;
337 comma:
338           ','           { $$ = ','; }
339         ;
340
341 optname:
342           NAME          { $$ = $1; }
343         | /* empty */   { $$ = lookup(curr_coord, 1); }
344         ;
345
346 expr:
347           NUMBER
348         | assign
349         | '(' string_expr ')'   { $$ = $2; }
350         | VARNAME               { $$ = getvar($1); }
351         | expr '+' expr         { $$ = $1 + $3; }
352         | expr '-' expr         { $$ = $1 - $3; }
353         | expr '*' expr         { $$ = $1 * $3; }
354         | expr '/' expr         { if ($3 == 0.0) {
355                                         ERROR "division by 0" WARNING; $3 = 1; }
356                                   $$ = $1 / $3; }
357         | expr '%' expr         { if ((long)$3 == 0) {
358                                         ERROR "mod division by 0" WARNING; $3 = 1; }
359                                   $$ = (long)$1 % (long)$3; }
360         | '-' expr %prec UMINUS { $$ = -$2; }
361         | '+' expr %prec UMINUS { $$ = $2; }
362         | '(' expr ')'          { $$ = $2; }
363         | LOG '(' expr ')'              { $$ = Log10($3); }
364         | EXP '(' expr ')'              { $$ = Exp($3 * log(10.0)); }
365         | expr '^' expr                 { $$ = pow($1, $3); }
366         | SIN '(' expr ')'              { $$ = sin($3); }
367         | COS '(' expr ')'              { $$ = cos($3); }
368         | ATAN2 '(' expr ',' expr ')'   { $$ = atan2($3, $5); }
369         | SQRT '(' expr ')'             { $$ = Sqrt($3); }
370         | RAND '(' ')'                  { $$ = (double)rand() / (double)RAND_MAX; }
371         | MAX '(' expr ',' expr ')'     { $$ = $3 >= $5 ? $3 : $5; }
372         | MIN '(' expr ',' expr ')'     { $$ = $3 <= $5 ? $3 : $5; }
373         | INT '(' expr ')'      { $$ = (long) $3; }
374         | expr GT expr          { $$ = $1 > $3; }
375         | expr LT expr          { $$ = $1 < $3; }
376         | expr LE expr          { $$ = $1 <= $3; }
377         | expr GE expr          { $$ = $1 >= $3; }
378         | expr EQ expr          { $$ = $1 == $3; }
379         | expr NE expr          { $$ = $1 != $3; }
380         | expr AND expr         { $$ = $1 && $3; }
381         | expr OR expr          { $$ = $1 || $3; }
382         | NOT expr              { $$ = !($2); }
383         ;
384 assign:
385           name '=' expr         { $$ = setvar($1, $3); }
386         ;
387
388 name:
389           NAME
390         | VARNAME
391         ;
392
393 optexpr:
394           expr
395         | /* empty */           { $$ = 0.0; }
396         ;