Commit | Line | Data |
---|---|---|
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 | */ | |
29 | line: | |
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 | */ | |
78 | func: | |
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 | } ; | |
101 | header: | |
102 | args autos = | |
103 | { | |
104 | if(context == lex4) | |
105 | invert($$, $2); | |
106 | } ; | |
107 | ||
108 | args: | |
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 | } ; | |
151 | autos: | |
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 | */ | |
174 | bcomand: | |
175 | rpar = | |
176 | { | |
177 | litflag = -1; | |
178 | } ; | |
179 | comand: | |
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 | */ | |
194 | fstat: | |
195 | numb cln realfstat = { | |
196 | $$ = $3; | |
197 | } | | |
198 | realfstat = $$ = $1; | |
199 | ||
200 | realfstat: | |
201 | stat | | |
202 | tran eol = | |
203 | { | |
204 | $$ = ccharp; | |
205 | *ccharp++ = BRAN0; | |
206 | } | | |
207 | tran expr eol = | |
208 | { | |
209 | $$ = $2; | |
210 | *ccharp++ = BRAN; | |
211 | } ; | |
212 | stat: | |
213 | statement eol ; | |
214 | statement: | |
215 | comnt = | |
216 | { | |
217 | litflag = 1; | |
218 | $$ = ccharp; | |
219 | *ccharp++ = COMNT; | |
220 | } | | |
221 | expr | | |
222 | hprint ; | |
223 | hprint: | |
224 | expr hsemi output ; | |
225 | output: | |
226 | expr = | |
227 | { | |
228 | *ccharp++ = PRINT; | |
229 | } | | |
230 | hprint ; | |
231 | hsemi: | |
232 | semi = | |
233 | { | |
234 | *ccharp++ = HPRINT; | |
235 | }; | |
236 | expr: | |
237 | e1 | | |
238 | monadic expr = | |
239 | { | |
240 | invert($$, $2); | |
241 | } | | |
242 | e1 dyadic expr = | |
243 | { | |
244 | invert($$, $3); | |
245 | } ; | |
246 | e1: | |
247 | e2 | | |
248 | e2 lsub subs rbkt = | |
249 | { | |
250 | invert($$, $3); | |
251 | *ccharp++ = INDEX; | |
252 | *ccharp++ = scount; | |
253 | scount = $2; | |
254 | } ; | |
255 | e2: | |
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 | } ; | |
300 | vector: | |
301 | number vector = | |
302 | { | |
303 | vcount++; | |
304 | } | | |
305 | number = | |
306 | { | |
307 | vcount = 1; | |
308 | } ; | |
309 | number: | |
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 | */ | |
321 | lsub: | |
322 | lbkt = | |
323 | { | |
324 | $$ = scount; | |
325 | scount = 1; | |
326 | } ; | |
327 | subs: | |
328 | sub | | |
329 | subs semi sub = | |
330 | { | |
331 | invert($$, $3); | |
332 | scount++; | |
333 | } ; | |
334 | sub: | |
335 | expr | | |
336 | = | |
337 | { | |
338 | $$ = ccharp; | |
339 | *ccharp++ = ELID; | |
340 | } ; | |
341 | ||
342 | /* | |
343 | * return a string of a monadic operator. | |
344 | */ | |
345 | monadic: | |
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 | } ; | |
372 | monad: | |
373 | m | | |
374 | msub | | |
375 | mondya = | |
376 | { | |
377 | $$++; | |
378 | } ; | |
379 | smonad: | |
380 | msub | | |
381 | mdsub = | |
382 | { | |
383 | $$ += 2; | |
384 | } ; | |
385 | ||
386 | /* | |
387 | * return a string of a dyadic operator. | |
388 | */ | |
389 | dyadic: | |
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 | } ; | |
417 | sdyad: | |
418 | mdcom = | |
419 | { | |
420 | $$ += 2; | |
421 | } ; | |
422 | ||
423 | /* | |
424 | * single expression subscript | |
425 | * as found on operators to select | |
426 | * a dimension. | |
427 | */ | |
428 | subr: | |
429 | lbkt expr rbkt = | |
430 | { | |
431 | $$ = $2; | |
432 | } ; | |
433 | ||
434 | /* | |
435 | * various combinations | |
436 | */ | |
437 | comp: | |
438 | com | com0 ; | |
439 | dyad: | |
440 | mondya | dscal | d | com0 | asg | com ; | |
441 | mdcom: | |
442 | mdsub | com ; | |
443 | mondya: | |
444 | mdscal | md | mdsub ; | |
445 | scalar: | |
446 | mdscal | dscal ; | |
447 | anyname: | |
448 | nam | nfun | mfun | dfun ; | |
449 | %% | |
450 | #include "tab.c" | |
451 | #include "lex.c" |