BSD 4 development
[unix-history] / usr / src / cmd / apl / apl.y
CommitLineData
d98b1ca7
BJ
1%term lex0, lex1, lex2, lex3, lex4, lex5, lex6
2%term lpar, rpar, lbkt, rbkt, eol, unk
3%term com, com0, strng, null, dot, cln
4%term quad, semi, comnt, tran, asg
5%term nam, numb, nfun, mfun, dfun
6%term comexpr, comnam, comnull
7
8%term dscal, mdscal
9%term m, d, md
10%term msub, mdsub,
11
12%{
13#include "apl.h"
14 int vcount;
15 int scount;
16 int litflag;
17 int nlexsym;
18 int context;
19 unsigned char *iline;
20 char *ccharp;
21%}
22
23%%
24
25/*
26 * line-at-a-time APL compiler.
27 * first lexical character gives context.
28 */
29line:
30
31/*
32 * immediate.
33 */
34 lex0 stat =
35 {
36 integ = ccharp[-1];
37 if(integ != ASGN && integ != PRINT)
38 *ccharp++ = PRINT;
39 *ccharp++ = EOL;
40 } |
41 lex0 bcomand comand eol =
42 {
43 *ccharp++ = IMMED;
44 *ccharp++ = $3;
45 } |
46/*
47 * quad
48 */
49 lex1 stat |
50/*
51 * function definition
52 */
53 lex2 func |
54/*
55 * function prolog
56 */
57 lex3 func |
58/*
59 * function epilog
60 */
61 lex4 func |
62/*
63 * function body
64 */
65 lex5 fstat ;
66
67
68
69
70
71
72
73
74
75/*
76 * function header
77 */
78func:
79 anyname asg header =
80 {
81 switch(context) {
82
83 case lex3:
84 name($$, AUTO);
85 *ccharp++ = ELID;
86 break;
87
88 case lex4:
89 integ = ccharp;
90 *ccharp++ = EOL;
91 name($$, NAME);
92 name($$, REST);
93 invert($3, integ);
94 }
95 } |
96 header =
97 {
98 if(context == lex3)
99 *ccharp++ = ELID;
100 } ;
101header:
102 args autos =
103 {
104 if(context == lex4)
105 invert($$, $2);
106 } ;
107
108args:
109 anyname anyname anyname =
110 {
111 $$ = ccharp;
112 switch(context) {
113
114 case lex2:
115 name($2, DF);
116 break;
117
118 case lex3:
119 name($1, ARG1);
120 name($3, ARG2);
121 break;
122
123 case lex4:
124 name($1, REST);
125 name($3, REST);
126 }
127 } |
128 anyname anyname =
129 {
130 $$ = ccharp;
131 switch(context) {
132
133 case lex2:
134 name($1, MF);
135 break;
136
137 case lex3:
138 name($2, ARG1);
139 break;
140
141 case lex4:
142 name($2, REST);
143 }
144 } |
145 anyname =
146 {
147 if(context == lex2)
148 name($$, NF);
149 $$ = ccharp;
150 } ;
151autos:
152 semi nam autos =
153 {
154 $$ = $3;
155 switch(context) {
156
157 case lex3:
158 name($2, AUTO);
159 break;
160
161 case lex4:
162 integ = name($2, REST);
163 invert($$, integ);
164 }
165 } |
166 eol =
167 {
168 $$ = ccharp;
169 } ;
170
171/*
172 * system commands
173 */
174bcomand:
175 rpar =
176 {
177 litflag = -1;
178 } ;
179comand:
180 comexpr expr |
181 comnam anyname =
182 {
183 name($2, NAME);
184 } |
185 comnull ;
186
187/*
188 * statement:
189 * comments
190 * expressions
191 * heterogeneous output
192 * transfers (in functions)
193 */
194fstat:
195 numb cln realfstat = {
196 $$ = $3;
197 } |
198 realfstat = $$ = $1;
199
200realfstat:
201 stat |
202 tran eol =
203 {
204 $$ = ccharp;
205 *ccharp++ = BRAN0;
206 } |
207 tran expr eol =
208 {
209 $$ = $2;
210 *ccharp++ = BRAN;
211 } ;
212stat:
213 statement eol ;
214statement:
215 comnt =
216 {
217 litflag = 1;
218 $$ = ccharp;
219 *ccharp++ = COMNT;
220 } |
221 expr |
222 hprint ;
223hprint:
224 expr hsemi output ;
225output:
226 expr =
227 {
228 *ccharp++ = PRINT;
229 } |
230 hprint ;
231hsemi:
232 semi =
233 {
234 *ccharp++ = HPRINT;
235 };
236expr:
237 e1 |
238 monadic expr =
239 {
240 invert($$, $2);
241 } |
242 e1 dyadic expr =
243 {
244 invert($$, $3);
245 } ;
246e1:
247 e2 |
248 e2 lsub subs rbkt =
249 {
250 invert($$, $3);
251 *ccharp++ = INDEX;
252 *ccharp++ = scount;
253 scount = $2;
254 } ;
255e2:
256 nfun =
257 {
258 $$ = name($$, FUN);
259 } |
260 nam =
261 {
262 $$ = name($$, NAME);
263 } |
264 strng =
265 {
266 $$ = ccharp;
267 ccharp += 2;
268 integ = iline[-1];
269 vcount = 0;
270 for(;;) {
271 if(*iline == '\n') {
272 nlexsym = unk;
273 break;
274 }
275 if(*iline == integ) {
276 iline++;
277 break;
278 }
279 *ccharp++ = *iline++;
280 vcount++;
281 }
282 $$->c[0] = QUOT;
283 $$->c[1] = vcount;
284 } |
285 vector =
286 {
287 *ccharp++ = CONST;
288 *ccharp++ = vcount;
289 invert($$, ccharp-2);
290 } |
291 lpar expr rpar =
292 {
293 $$ = $2;
294 } |
295 quad =
296 {
297 $$ = ccharp;
298 *ccharp++ = $1;
299 } ;
300vector:
301 number vector =
302 {
303 vcount++;
304 } |
305 number =
306 {
307 vcount = 1;
308 } ;
309number:
310 numb =
311 {
312 $$ = ccharp;
313 for(integ=0; integ<SDAT; integ++)
314 *ccharp++ = datum.c[integ];
315 } ;
316
317/*
318 * indexing subscripts
319 * optional expressions separated by semi
320 */
321lsub:
322 lbkt =
323 {
324 $$ = scount;
325 scount = 1;
326 } ;
327subs:
328 sub |
329 subs semi sub =
330 {
331 invert($$, $3);
332 scount++;
333 } ;
334sub:
335 expr |
336 =
337 {
338 $$ = ccharp;
339 *ccharp++ = ELID;
340 } ;
341
342/*
343 * return a string of a monadic operator.
344 */
345monadic:
346 monad =
347 {
348 $$ = ccharp;
349 *ccharp++ = $1;
350 } |
351 smonad subr =
352 {
353 $$ = $2;
354 *ccharp++ = $1+1;
355 } |
356 mfun =
357 {
358 $$ = name($$, FUN);
359 } |
360 scalar comp =
361 {
362 $$ = ccharp;
363 *ccharp++ = $2+1;
364 *ccharp++ = $1;
365 } |
366 scalar com subr =
367 {
368 $$ = $3;
369 *ccharp++ = $2+3;
370 *ccharp++ = $1;
371 } ;
372monad:
373 m |
374 msub |
375 mondya =
376 {
377 $$++;
378 } ;
379smonad:
380 msub |
381 mdsub =
382 {
383 $$ += 2;
384 } ;
385
386/*
387 * return a string of a dyadic operator.
388 */
389dyadic:
390 dyad =
391 {
392 $$ = ccharp;
393 *ccharp++ = $1;
394 } |
395 sdyad subr =
396 {
397 $$ = $2;
398 *ccharp++ = $1;
399 } |
400 dfun =
401 {
402 $$ = name($$, FUN);
403 } |
404 null dot scalar =
405 {
406 $$ = ccharp;
407 *ccharp++ = OPROD;
408 *ccharp++ = $3;
409 } |
410 scalar dot scalar =
411 {
412 $$ = ccharp;
413 *ccharp++ = IPROD;
414 *ccharp++ = $1;
415 *ccharp++ = $3;
416 } ;
417sdyad:
418 mdcom =
419 {
420 $$ += 2;
421 } ;
422
423/*
424 * single expression subscript
425 * as found on operators to select
426 * a dimension.
427 */
428subr:
429 lbkt expr rbkt =
430 {
431 $$ = $2;
432 } ;
433
434/*
435 * various combinations
436 */
437comp:
438 com | com0 ;
439dyad:
440 mondya | dscal | d | com0 | asg | com ;
441mdcom:
442 mdsub | com ;
443mondya:
444 mdscal | md | mdsub ;
445scalar:
446 mdscal | dscal ;
447anyname:
448 nam | nfun | mfun | dfun ;
449%%
450#include "tab.c"
451#include "lex.c"