1
2 /*
3 # Sfront, a SAOL to C translator
4 # This file: Works with bison's parser.y SAOL file
5 #
6 # Copyright (c) 1999-2006, Regents of the University of California
7 # All rights reserved.
8 #
9 # Redistribution and use in source and binary forms, with or without
10 # modification, are permitted provided that the following conditions are
11 # met:
12 #
13 # Redistributions of source code must retain the above copyright
14 # notice, this list of conditions and the following disclaimer.
15 #
16 # Redistributions in binary form must reproduce the above copyright
17 # notice, this list of conditions and the following disclaimer in the
18 # documentation and/or other materials provided with the distribution.
19 #
20 # Neither the name of the University of California, Berkeley nor the
21 # names of its contributors may be used to endorse or promote products
22 # derived from this software without specific prior written permission.
23 #
24 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #
36 # Maintainer: John Lazzaro, lazzaro@cs.berkeley.edu
37 */
38
39
40 #include "tree.h"
41
42
43 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
44 /* */
45 /* The parser.y file holds the SAOL grammer sfront uses. This */
46 /* parsehelp.c file contains the functions parser.y rules */
47 /* use to build the initial parse tree. */
48 /* */
49 /* parsehelp.c begins with a set of sections, for the top */
50 /* level complicated parser.y rules, scanning the parser.y */
51 /* file from top to bottom. Following these sections are */
52 /* sections devoted to simpler generic functions used by */
53 /* by many parser.y rules, and finally utility functions. */
54 /* */
55 /*______________________________________________________________*/
56
57 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
58 /* */
59 /* Top-level functions for instrument declarations. */
60 /* */
61 /*______________________________________________________________*/
62
63 extern void tableexprcheck(void);
64
65 /***********************************************************************/
66 /* instrdecl: INSTR IDENT LP identlist RP miditag LC vardecls block RC */
67 /***********************************************************************/
68
make_instrdecl(tnode * t_instr,tnode * t_ident,tnode * t_lp,tnode * t_identlist,tnode * t_rp,tnode * t_miditag,tnode * t_lc,tnode * t_vardecls,tnode * t_block,tnode * t_rc)69 tnode * make_instrdecl(tnode * t_instr, tnode * t_ident, tnode * t_lp,
70 tnode * t_identlist, tnode * t_rp,
71 tnode * t_miditag, tnode * t_lc,
72 tnode * t_vardecls, tnode * t_block,
73 tnode * t_rc)
74
75 {
76 tnode * retptr;
77 int symstate;
78 tnode * tptr;
79 sigsym * sptr;
80
81 retptr = make_tnode("<instrdecl>",S_INSTRDECL);
82
83 /* make sure name is unique over instr and opcodes */
84
85 if ((getsym(&opcodenametable, t_ident) != NULL) ||
86 wavegeneratorname(t_ident) || coreopcodename(t_ident))
87 {
88 printf("Error: Instr name %s not unique.\n\n",
89 t_ident->val);
90 showerrorplace(t_ident->linenum, t_ident->filename);
91 }
92 symstate = addsym(&instrnametable, t_ident);
93 symcheck(symstate, t_ident);
94
95 instrnametable->kind = K_INSTRNAME;
96 instrnametable->obus = NULL;
97 instrnametable->defnode = retptr;
98 instrnametable->width = OUTCHANNELSWIDTH;
99 instrnametable->maxifstate = conditionalblocks;
100
101 /* add nodes */
102 retptr->down = t_instr;
103
104 t_instr->next = t_ident;
105 t_ident->next = t_lp;
106
107 t_lp->next = make_tnode("<identlist>",S_IDENTLIST);
108 t_lp->next->down = t_identlist;
109 t_lp->next->next = t_rp;
110
111 if (t_miditag == NULL)
112 {
113 t_rp->next = make_tnode("<miditag>",S_MIDITAG);
114 t_rp->next->next = t_lc;
115 }
116 else
117 {
118 instrnametable->miditag = 1;
119 t_rp->next = t_miditag;
120 t_miditag->next = t_lc;
121 tptr = t_miditag->down->next->down;
122 while (tptr != NULL)
123 {
124 addvsymsort(&instrpresets, tptr->val, K_PRESET);
125 sptr = getvsym(&instrpresets, tptr->val);
126
127 /* addvsymsort sets sptr->width to atoi(tptr->val) */
128
129 if (sptr->width > maxmidipreset)
130 maxmidipreset = sptr->width;
131 sptr->defnode = make_tnode(t_ident->val, S_INSTR);
132 sptr->defnode->sptr = instrnametable;
133 tptr = tptr->next;
134 }
135 }
136
137 t_lc->next = make_tnode("<vardecls>",S_VARDECLS);
138 t_lc->next->down = t_vardecls;
139 t_lc->next->next = make_tnode("<block>",S_BLOCK);
140
141 t_lc->next->next->down = t_block;
142 t_lc->next->next->next = t_rc;
143
144 tableexprcheck();
145
146 retptr->sptr = reversetable(locsymtable);
147 locsymtable = NULL;
148
149 retptr->optr = locopcodecalls;
150 locopcodecalls = NULL;
151
152 retptr->dptr = locdyncalls;
153 locdyncalls = NULL;
154
155 isaninstr = 0;
156 conditionalblocks = 0;
157
158 return retptr;
159 }
160
161
162 extern void reservednames(tnode *);
163
164 /***********************************************************************/
165 /* adds parameter fields into symbol table before instr parse begins */
166 /***********************************************************************/
167
make_instrpfields(tnode * t_identlist)168 void make_instrpfields(tnode * t_identlist)
169
170 {
171 int symstate;
172 int i = 0;
173 tnode * tptr = t_identlist;
174
175 while (tptr != NULL)
176 if (tptr->ttype == S_IDENT)
177 {
178 i++;
179 reservednames(tptr);
180 symstate = addsym(&locsymtable, tptr);
181 symcheck(symstate,tptr);
182 locsymtable->kind = K_PFIELD;
183 tptr->sptr = locsymtable;
184 tptr->width = locsymtable->width = 1;
185 tptr->rate = locsymtable->rate = IRATETYPE;
186 tptr = tptr->next;
187 }
188 else
189 tptr = tptr->next;
190
191 if (i > 255)
192 {
193 printf("Error: Instr or template has more than 255 parameters.\n\n");
194 showerrorplace(t_identlist->linenum, t_identlist->filename);
195 }
196
197 if (i > numpfields)
198 numpfields = i;
199
200 isaninstr = 1;
201 conditionalblocks = 0;
202
203 }
204
205
206 /***********************************************************************/
207 /* make_miditag: part of instr definition */
208 /***********************************************************************/
209
make_miditag(tnode * t_preset,tnode * t_intlist)210 tnode * make_miditag(tnode * t_preset, tnode * t_intlist)
211
212 {
213 tnode * retptr;
214
215 retptr = make_tnode("<miditag>",S_MIDITAG);
216 retptr->down = t_preset;
217 if (strcmp("preset",t_preset->val))
218 {
219 printf("Error: Parser expected token preset.\n\n");
220 showerrorplace(t_preset->linenum, t_preset->filename);
221 }
222 t_preset->next = make_tnode("<intlist>",S_INTLIST);
223 t_preset->next->down = t_intlist;
224
225 return retptr;
226 }
227
228
229 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
230 /* */
231 /* Top-level functions for opcode declarations. */
232 /* */
233 /*______________________________________________________________*/
234
235 /***********************************************************************/
236 /* optype IDENT LP paramlist RP LC opvardecls block RC */
237 /***********************************************************************/
238
make_opcodedecl(tnode * t_optype,tnode * t_ident,tnode * t_lp,tnode * t_paramlist,tnode * t_rp,tnode * t_lc,tnode * t_opvardecls,tnode * t_block,tnode * t_rc)239 tnode * make_opcodedecl(tnode * t_optype, tnode * t_ident, tnode * t_lp,
240 tnode * t_paramlist, tnode * t_rp, tnode * t_lc,
241 tnode * t_opvardecls, tnode * t_block, tnode * t_rc)
242 {
243
244 tnode * retptr;
245 tnode * tptr;
246 tnode ** rstat;
247
248 retptr = make_tnode("<opcodedecl>",S_OPCODEDECL);
249 opcodenametable->defnode = retptr;
250 opcodenametable->maxifstate = conditionalblocks;
251
252 /* add nodes */
253
254 retptr->down = t_optype;
255
256 t_optype->next = t_ident;
257 t_ident->next = t_lp;
258
259 t_lp->next = make_tnode("<paramlist>",S_PARAMLIST);
260 t_lp->next->down = t_paramlist;
261 t_lp->next->next = t_rp;
262
263 t_lp->next->rate = UNKNOWN;
264 tptr = t_paramlist;
265 while (tptr != NULL)
266 {
267 if ( (tptr->ttype == S_PARAMDECL) &&
268 (tptr->rate < XRATETYPE) &&
269 (tptr->rate > t_lp->next->rate) &&
270 ((tptr->vartype == SCALARTYPE) || (tptr->vartype == VECTORTYPE)))
271 t_lp->next->rate = tptr->rate;
272 tptr = tptr->next;
273 }
274
275 t_rp->next = t_lc;
276
277 t_lc->next = make_tnode("<opvardecls>",S_OPVARDECLS);
278 t_lc->next->down = t_opvardecls;
279 t_lc->next->next = make_tnode("<block>",S_BLOCK);
280
281 /* add return statement on end it needed */
282
283 if (t_block)
284 {
285 tptr = t_block;
286 while (tptr->next != NULL)
287 tptr = tptr->next;
288 rstat = &(tptr->next);
289 }
290 else
291 rstat = &t_block;
292
293 if ((t_block == NULL) || (tptr->down->ttype != S_RETURN))
294 {
295 *rstat = make_tnode("<statement>",S_STATEMENT);
296 (*rstat)->down = make_tnode("return",S_RETURN);
297 (*rstat)->down->next = make_tnode("(",S_LP);
298 (*rstat)->down->next->next = make_tnode("<exprlist>",S_EXPRLIST);
299 (*rstat)->down->next->next->next = make_tnode(")",S_RP);
300 tptr = (*rstat)->down->next->next;
301 tptr->down = make_tnode("<expr>",S_EXPR);
302 tptr->down->rate = IRATETYPE;
303 tptr->down->vol = CONSTANT;
304 tptr->down->down = make_tnode("0.0",S_NUMBER);
305 tptr->down->down->rate = IRATETYPE;
306 tptr->down->down->vol = CONSTANT;
307 }
308
309 t_lc->next->next->down = t_block;
310 t_lc->next->next->next = t_rc;
311
312 tableexprcheck();
313
314 retptr->sptr = reversetable(locsymtable);
315 locsymtable = NULL;
316
317 if (t_optype->ttype != S_AOPCODE)
318 {
319 tptr = locopcodecalls;
320 while (tptr != NULL)
321 {
322 if (coreopcodespecial(tptr))
323 {
324 printf("Error: Specialop %s may not appear in ", tptr->val);
325
326 switch (t_optype->ttype) {
327 case S_IOPCODE:
328 printf("an iopcode definition.\n");
329 break;
330 case S_KOPCODE:
331 printf("a kopcode definition.\n");
332 break;
333 case S_OPCODE:
334 printf("a polymorphic opcode definition.\n");
335 break;
336 }
337 showerrorplace(tptr->optr->down->linenum,
338 tptr->optr->down->filename);
339 }
340 tptr = tptr->next;
341 }
342 }
343
344 retptr->optr = locopcodecalls;
345 locopcodecalls = NULL;
346
347 retptr->dptr = locdyncalls;
348 locdyncalls = NULL;
349
350 return retptr;
351
352 }
353
354 /***********************************************************************/
355 /* optype IDENT {make_opcodetype();} ... */
356 /***********************************************************************/
357
make_opcodetype(tnode * t_optype,tnode * t_ident)358 void make_opcodetype(tnode * t_optype, tnode * t_ident)
359
360 {
361
362 int symstate;
363
364 /* make sure name is unique over instr and opcodes */
365
366 if ((getsym(&instrnametable, t_ident) != NULL) ||
367 wavegeneratorname(t_ident) || coreopcodename(t_ident))
368 {
369 printf("Error: Opcode name %s not unique.\n\n",
370 t_ident->val);
371 showerrorplace(t_ident->linenum, t_ident->filename);
372 }
373 symstate = addsym(&opcodenametable, t_ident);
374 symcheck(symstate, t_ident);
375 opcodenametable->rate = t_optype->rate;
376 opcodenametable->kind = K_OPCODENAME;
377 opcodenametable->width = UNKNOWN;
378
379 isaninstr = 0;
380 nonpolyparams = 0;
381 conditionalblocks = 0;
382
383 }
384
385
386 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
387 /* */
388 /* Top-level function for the global block. */
389 /* */
390 /*______________________________________________________________*/
391
392 /***********************************************************************/
393 /* globaldecl: GLOBAL LC globalblock RC */
394 /***********************************************************************/
395
make_globaldecl(tnode * t_global,tnode * t_lc,tnode * t_globalblock,tnode * t_rc)396 tnode * make_globaldecl(tnode * t_global, tnode * t_lc,
397 tnode * t_globalblock, tnode * t_rc)
398
399
400 {
401 tnode * retptr;
402 sigsym * ptr;
403 tnode * tptr;
404
405 globalblockcount++;
406 if (isocompliant && (globalblockcount > 1))
407 {
408 printf("Error: Only one global block per orchestra.\n\n");
409 showerrorplace(t_global->linenum, t_global->filename);
410 }
411 suspendvarchecks = 0;
412 if (globalblockcount == 1)
413 {
414 retptr = make_tnode("<globalblock>",S_GLOBALBLOCK);
415 groot = retptr->down = t_globalblock;
416 retptr = make_stree(t_global,t_lc,retptr,t_rc,
417 "<globaldecl>",S_GLOBALDECL);
418 }
419 else
420 {
421 if (groot)
422 {
423 tptr = groot;
424 while (tptr->next != NULL)
425 tptr = tptr->next;
426 tptr->next = t_globalblock;
427 }
428 else
429 groot = t_globalblock;
430 retptr = NULL;
431 }
432 ptr = locsymtable;
433 while (ptr != NULL)
434 {
435 if ((ptr->kind == K_IMPORT) ||
436 (ptr->kind == K_EXPORT)||(ptr->kind == K_IMPORTEXPORT))
437 {
438 printf("Error: Import/export tags in global declaration.\n");
439 showerrorplace(ptr->defnode->linenum, ptr->defnode->filename);
440 }
441 if (ptr->vartype == TMAPTYPE)
442 {
443 printf("Error: Tablemap in global declaration.\n");
444 showerrorplace(ptr->defnode->down->linenum,
445 ptr->defnode->down->filename);
446 }
447 if (ptr->rate == ARATETYPE)
448 {
449 printf("Error: Global declaration may not be a-rate.\n");
450 showerrorplace(ptr->defnode->linenum, ptr->defnode->filename);
451 }
452 ptr = ptr->next;
453 }
454
455 tptr = locopcodecalls;
456 while (tptr != NULL)
457 {
458 if (tptr->ttype == S_OPARRAYDECL)
459 {
460 printf("Error: Global declarations may not be oparrays.\n");
461 showerrorplace(tptr->optr->down->linenum, tptr->optr->down->filename);
462 }
463 tptr = tptr->next;
464 }
465
466 if (globalsymtable)
467 {
468 ptr = globalsymtable;
469 while (ptr->next != NULL)
470 ptr = ptr->next;
471 ptr->next = reversetable(locsymtable);
472 }
473 else
474 globalsymtable = reversetable(locsymtable);
475
476 if (globalopcodecalls)
477 {
478 tptr = globalopcodecalls;
479 while (tptr->next != NULL)
480 tptr = tptr->next;
481 tptr->next = locopcodecalls;
482 }
483 else
484 globalopcodecalls = locopcodecalls;
485
486 locsymtable = NULL;
487 locopcodecalls = NULL;
488 return retptr;
489
490 }
491
492 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
493 /* */
494 /* Top-level functions for templates. */
495 /* */
496 /*______________________________________________________________*/
497
498
499 /************************************************************************/
500 /*templatedecl : TEMPLATE LT identlist GT LP identlist RP */
501 /* MAP LC identlist RC */
502 /* WITH {make_templatepfields($6,$10);} LC mapblock RC */
503 /* LC vardecls block RC */
504 /* only non-terminals sent to function */
505 /* needs to be updated to handle midi */
506 /************************************************************************/
507
make_templatedecl(tnode * t_instrs,tnode * t_miditags,tnode * t_pfields,tnode * t_maptokens,tnode * t_mapargs,tnode * t_vardecls,tnode * t_block)508 tnode * make_templatedecl(tnode * t_instrs, tnode * t_miditags,
509 tnode * t_pfields, tnode * t_maptokens,
510 tnode * t_mapargs, tnode * t_vardecls,
511 tnode * t_block)
512
513 {
514 tnode * ptokens; /* identlist for pfield string*/
515 tnode * vtokens;
516 tnode * retptr = NULL;
517 tnode * cptr = NULL; /* initialization not needed */
518 tnode * tptr;
519 tnode * lptr;
520 tnode * mptr;
521 sigsym * templatevars;
522 sigsym * sptr;
523 int symstate;
524 int midinum;
525
526 suspendvarchecks = 0;
527 isaninstr = 1;
528
529 tlocsymtable = reversetable(locsymtable);
530 tlocopcodecalls = locopcodecalls;
531 tlocdyncalls = locdyncalls;
532
533 while (t_instrs != NULL)
534 {
535 if (t_instrs->ttype == S_IDENT)
536 {
537 /* build instr structure */
538 if (retptr == NULL)
539 retptr = cptr = make_tnode("<instrdecl>",S_INSTRDECL);
540 else
541 {
542 cptr->next = make_tnode("<instrdecl>",S_INSTRDECL);
543 cptr = cptr->next;
544 }
545 cptr->down = make_tnode("INSTR",S_INSTR);
546 cptr->down->next = make_tnode(t_instrs->val, S_IDENT);
547 cptr->down->next->next = make_tnode("(",S_LP);
548 cptr->down->next->next->next = ptokens =
549 make_tnode("<identlist>",S_IDENTLIST);
550 ptokens->next = make_tnode(")",S_RP);
551 ptokens->next->next = make_tnode("<miditag>",S_MIDITAG);
552
553 ptokens->next->next->next = make_tnode("{",S_LC);
554 ptokens->next->next->next->next = vtokens =
555 make_tnode("<vardecls>",S_VARDECLS);
556 vtokens->next = make_tnode("<block>",S_BLOCK);
557 vtokens->next->next = make_tnode("}",S_RC);
558
559 /* check in name */
560
561 if ((getsym(&opcodenametable, t_instrs) != NULL) ||
562 wavegeneratorname(t_instrs) || coreopcodename(t_instrs))
563 {
564 printf("Error: Template instr name %s not unique.\n\n",
565 t_instrs->val);
566 showerrorplace(t_instrs->linenum, t_instrs->filename);
567 }
568 symstate = addsym(&instrnametable, t_instrs);
569 symcheck(symstate, t_instrs);
570
571 instrnametable->kind = K_INSTRNAME;
572 instrnametable->obus = NULL;
573 instrnametable->defnode = cptr;
574 instrnametable->width = OUTCHANNELSWIDTH;
575 instrnametable->maxifstate = conditionalblocks;
576
577 if (t_miditags != NULL)
578 {
579 instrnametable->miditag = 1;
580 mptr = t_miditags->down;
581 t_miditags = t_miditags->next;
582 while (mptr != NULL)
583 {
584 if (mptr->ttype == S_EXPR)
585 {
586 co_constcollapse(mptr);
587
588 if (((mptr->down->ttype != S_INTGR) && (mptr->down->ttype != S_NUMBER))
589 || (mptr->down->next != NULL))
590 {
591 printf("Error: Template MIDI num must resolve to a constant.\n\n"
592 );
593 while (mptr->down != NULL)
594 mptr = mptr->down;
595 showerrorplace(mptr->linenum, mptr->filename);
596 }
597 if (mptr->down->ttype == S_NUMBER)
598 {
599 midinum = (int)(atof(mptr->down->val)+0.5);
600 vmcheck(mptr->down->val = (char *) calloc(20, 1));
601 sprintf(mptr->down->val, "%i", midinum);
602 mptr->down->ttype = S_INTGR;
603 mptr->down->res = ASINT;
604 }
605
606 addvsymsort(&instrpresets, mptr->down->val, K_PRESET);
607 sptr = getvsym(&instrpresets, mptr->down->val);
608
609 /* addvsymsort sets sptr->width to atoi(mptr->down->val) */
610
611 if (sptr->width > maxmidipreset)
612 maxmidipreset = sptr->width;
613 sptr->defnode = make_tnode(t_instrs->val, S_INSTR);
614 sptr->defnode->sptr = instrnametable;
615
616 }
617 mptr = mptr->next;
618 }
619 }
620
621 /* build substitution list */
622
623 if (t_mapargs == NULL)
624 lptr = NULL;
625 else
626 {
627 lptr = t_mapargs->down;
628 t_mapargs = t_mapargs->next;
629 }
630
631 templatevars = NULL;
632 tptr = t_maptokens;
633 while (tptr != NULL)
634 {
635 if (tptr->ttype == S_IDENT)
636 {
637 reservednames(tptr);
638 symcheck(addsym(&templatevars,tptr),tptr);
639 templatevars->defnode = lptr;
640 if (lptr == NULL)
641 {
642 printf("Error: Not enough template elements for %s.\n\n",
643 tptr->val);
644 showerrorplace(tptr->linenum, tptr->filename);
645 }
646 lptr = lptr->next; /* skip over comma */
647 if (lptr != NULL)
648 lptr = lptr->next;
649 templatevars->defnode->next = NULL;
650 }
651 tptr = tptr->next;
652 }
653
654 cptr->sptr = locsymtable = sclone(tlocsymtable);
655 locopcodecalls = tclone(tlocopcodecalls);
656 locdyncalls = tclone(tlocdyncalls);
657 vtokens->next->down = treeclone(t_block,&templatevars,DOSUB);
658 vtokens->down = treeclone(t_vardecls,&templatevars,DOSUB);
659 cptr->optr = locopcodecalls;
660 cptr->dptr = locdyncalls;
661 varupdate(vtokens->next->down,&locsymtable);
662 varupdate(vtokens->down,&locsymtable);
663 tableexprcheck();
664 }
665 t_instrs = t_instrs->next;
666 }
667
668 locsymtable = NULL;
669 locopcodecalls = NULL;
670 locdyncalls = NULL;
671 isaninstr = 0;
672 conditionalblocks = 0;
673 return retptr;
674 }
675
676 /***********************************************************************/
677 /* patches opcode and oparray calls in template maplists */
678 /***********************************************************************/
679
templateopcodepatch(void)680 void templateopcodepatch(void)
681
682 {
683 tnode * tptr = locopcodecalls;
684
685
686 /* reset state machine -- for null mapblocks */
687
688 lexstatemachine = TEMPLATE_REST;
689
690 /* patch opcalls */
691
692 while (tptr != NULL)
693 {
694 if (tptr->ttype == S_OPARRAYCALL)
695 {
696 tptr->optr->optr = tptr->optr->down->optr = &maplistoparraycall;
697 }
698 else
699 {
700 tptr->optr->optr = tptr->optr->down->optr = &maplistopcall;
701 }
702 tptr = tptr->next;
703 }
704
705 locopcodecalls = NULL;
706 }
707
708 /***********************************************************************/
709 /* adds parameter fields into symbol table before template parse begins*/
710 /***********************************************************************/
711
make_templatepfields(tnode * t_preset,tnode * t_identlist)712 void make_templatepfields(tnode * t_preset, tnode * t_identlist)
713
714 {
715 if (t_preset != NULL)
716 {
717 if (strcmp("preset",t_preset->val))
718 {
719 printf("Error: Syntax error in template miditag.\n\n");
720 showerrorplace(t_preset->linenum, t_preset->filename);
721 }
722 }
723 make_instrpfields(t_identlist);
724 suspendvarchecks = 1;
725
726 lexstatemachine = TEMPLATE_ACTIVE;
727
728 }
729
730 /***********************************************************************/
731 /* make_mapblock: part of templatedecl definition */
732 /***********************************************************************/
733
make_mapblock(tnode * t_list,tnode * t_map)734 tnode * make_mapblock(tnode * t_list, tnode * t_map)
735
736
737 {
738 tnode * retptr;
739 tnode * ptr;
740
741 ptr = make_tnode("<mapblock>",S_BLOCK);
742 ptr->down = t_map;
743 if (t_list == NULL)
744 {
745 retptr = ptr;
746 }
747 else
748 {
749 retptr = t_list;
750 while (t_list->next != NULL)
751 t_list = t_list->next;
752 t_list->next = ptr;
753 }
754
755 return retptr;
756 }
757
758
759 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
760 /* */
761 /* Top-level functions for items exclusive to the global block. */
762 /* */
763 /* */
764 /* globaldef : rtparam */
765 /* | routedef */
766 /* | senddef */
767 /* | seqdef */
768 /* */
769 /*______________________________________________________________*/
770
771 /***********************************************************************/
772 /*rtparam : SRATE INTGR SEM {$$ = make_rtparam($1,$2,$3);}*/
773 /* | KRATE INTGR SEM {$$ = make_rtparam($1,$2,$3);}*/
774 /* | INCHANNELS INTGR SEM {$$ = make_rtparam($1,$2,$3);}*/
775 /* | OUTCHANNELS INTGR SEM {$$ = make_rtparam($1,$2,$3);}*/
776 /* | INTERP INTGR SEM {$$ = make_rtparam($1,$2,$3);}*/
777 /***********************************************************************/
778
make_rtparam(tnode * t_param,tnode * t_intgr,tnode * t_sem)779 tnode * make_rtparam(tnode * t_param, tnode * t_intgr, tnode * t_sem)
780
781
782 {
783 tnode * retptr;
784
785 retptr = make_stree(t_param, t_intgr, t_sem, NULL, "<rtdef>", S_RTDEF);
786 switch (t_param->ttype) {
787 case S_SRATE:
788 if (srate >= 0)
789 {
790 printf("Error: Srate parameter may only be set once.\n\n");
791 showerrorplace(t_param->linenum, t_param->filename);
792 }
793 sscanf(t_intgr->val,"%i",&srate);
794 if ((srate < 4000) || (srate > 96000))
795 {
796 printf("Error: Srate parameter out of range (4000-96000).\n\n");
797 showerrorplace(t_param->linenum, t_param->filename);
798 }
799 if (srate < krate)
800 {
801 printf("Error: Parameter srate < krate.\n\n");
802 showerrorplace(t_param->linenum, t_param->filename);
803 }
804 break;
805 case S_KRATE:
806 if (krate >= 0)
807 {
808 printf("Error: Krate parameter may only be set once.\n\n");
809 showerrorplace(t_param->linenum, t_param->filename);
810 }
811 sscanf(t_intgr->val,"%i",&krate);
812 if ((krate < 1) || (krate > 96000))
813 {
814 printf("Error: Krate parameter out of range (1-96000).\n\n");
815 showerrorplace(t_param->linenum, t_param->filename);
816 }
817 if ((srate > 0) && (srate < krate))
818 {
819 printf("Error: Parameter krate > srate.\n\n");
820 showerrorplace(t_param->linenum, t_param->filename);
821 }
822 break;
823 case S_INCHANNELS:
824 if (inchannels >= 0)
825 {
826 printf("Error: Inchannels parameter may only be set once.\n\n");
827 showerrorplace(t_param->linenum, t_param->filename);
828 }
829 sscanf(t_intgr->val,"%i",&inchannels);
830 if ((inchannels < 0))
831 {
832 printf("Error: Inchannels parameter must be >= 0.\n\n");
833 showerrorplace(t_param->linenum, t_param->filename);
834 }
835 break;
836 case S_OUTCHANNELS:
837 if (outchannels >= 0)
838 {
839 printf("Error: Outchannels parameter may only be set once.\n\n");
840 showerrorplace(t_param->linenum, t_param->filename);
841 }
842 sscanf(t_intgr->val,"%i",&outchannels);
843 if ((outchannels < 0))
844 {
845 printf("Error: Outchannels parameter must be >= 0.\n\n");
846 showerrorplace(t_param->linenum, t_param->filename);
847 }
848 break;
849 case S_INTERP:
850 if (interp >= 0)
851 {
852 printf("Error: Interp parameter may only be set once.\n\n");
853 showerrorplace(t_param->linenum, t_param->filename);
854 }
855 sscanf(t_intgr->val,"%i",&interp);
856 if ((interp != INTERP_LINEAR) && (interp != INTERP_SINC))
857 {
858 printf("Error: Interp parameter out of range (0-1).\n\n");
859 showerrorplace(t_param->linenum, t_param->filename);
860 }
861 break;
862 }
863
864
865 return retptr;
866 }
867
868 /***********************************************************************/
869 /* routedef: ROUTE LP IDENT COM identlist RP SEM */
870 /***********************************************************************/
871
make_routedef(tnode * t_route,tnode * t_lp,tnode * t_ident,tnode * t_com,tnode * t_identlist,tnode * t_rp,tnode * t_sem)872 tnode * make_routedef(tnode * t_route, tnode * t_lp, tnode * t_ident,
873 tnode * t_com, tnode * t_identlist, tnode * t_rp,
874 tnode * t_sem)
875
876
877 {
878 tnode * retptr;
879
880 retptr = make_stree(t_route, t_lp, t_ident, t_com, "<routedef>", S_ROUTEDEF);
881 t_com->next= make_tnode("<identlist>",S_IDENTLIST);
882 t_com->next->down = t_identlist;
883 t_com->next->next = t_rp;
884 t_rp->next = t_sem;
885
886 if (t_identlist == NULL)
887 {
888 printf("Error: Route statements must reference an instrument.\n\n");
889 showerrorplace(t_route->linenum, t_route->filename);
890 }
891 if (!strcmp(t_ident->val,"input_bus"))
892 {
893 printf("Error: Route statements references input_bus.\n\n");
894 showerrorplace(t_route->linenum, t_route->filename);
895 }
896
897 return retptr;
898 }
899
900 /***********************************************************************/
901 /* senddef: SEND LP IDENT SEM exprlist SEM identlist RP SEM */
902 /***********************************************************************/
903
make_senddef(tnode * t_send,tnode * t_lp,tnode * t_ident,tnode * t_sem1,tnode * t_exprlist,tnode * t_sem2,tnode * t_namelist,tnode * t_rp,tnode * t_sem3)904 tnode * make_senddef(tnode * t_send, tnode * t_lp, tnode * t_ident,
905 tnode * t_sem1, tnode * t_exprlist, tnode * t_sem2,
906 tnode * t_namelist, tnode * t_rp, tnode * t_sem3)
907
908
909 {
910 tnode * retptr, * ptr;
911 char * name;
912
913 if (t_namelist == NULL)
914 {
915 printf("Error: Send statement must reference a bus.\n\n");
916 showerrorplace(t_send->linenum, t_send->filename);
917 }
918
919 retptr = make_stree(t_send, t_lp, t_ident, t_sem1, "<senddef>", S_SENDDEF);
920 t_sem1->next = make_tnode("<exprlist>",S_EXPRLIST);
921 t_sem1->next->down = t_exprlist;
922 t_sem1->next->next = t_sem2;
923 t_sem2->next = make_tnode("<namelist>",S_NAMELIST);
924 t_sem2->next->down = t_namelist;
925 t_sem2->next->next = t_rp;
926 t_rp->next = t_sem3;
927
928 /* send statement defines buses - we log definitions below */
929
930 ptr = t_namelist;
931 while (ptr != NULL)
932 if (ptr->ttype == S_NAME)
933 {
934 name = ptr->down->val;
935 if ((addvsym(&busnametable, name, K_BUSNAME) != INSTALLED)
936 &&(!strcmp(name, "output_bus")))
937 {
938 printf("Error: Multiple definition of output_bus.\n\n");
939 showerrorplace(ptr->down->linenum, ptr->down->filename);
940 }
941 if (!strcmp(name,"output_bus"))
942 {
943 if (outputbusinstance != NULL)
944 {
945 printf("Error: Output_bus sent to multiple instances.\n\n");
946 showerrorplace(ptr->down->linenum, ptr->down->filename);
947 }
948 outputbusinstance = make_tnode(t_ident->val, S_INSTANCE);
949 outputbusinstance->down = retptr;
950 }
951 busnametable->defnode = retptr->down; /* send command creating bus */
952 busnametable->width = 0;
953 ptr->sptr = getsym(&busnametable,ptr->down);
954 ptr = ptr->next;
955 }
956 else
957 ptr = ptr->next;
958
959
960 return retptr;
961 }
962
963 /***********************************************************************/
964 /* seqdef: SEQUENCE LP identlist RP SEM */
965 /***********************************************************************/
966
make_seqdef(tnode * t_sequence,tnode * t_lp,tnode * t_identlist,tnode * t_rp,tnode * t_sem)967 tnode * make_seqdef(tnode * t_sequence, tnode * t_lp, tnode * t_identlist,
968 tnode * t_rp, tnode * t_sem)
969
970
971 {
972 tnode * retptr;
973
974 retptr = make_stree(t_sequence, t_lp, make_tnode("<identlist>",S_IDENTLIST),
975 t_rp, "<seqdef>", S_SEQDEF);
976 t_rp->next = t_sem;
977 t_lp->next->down = t_identlist;
978 if ((t_identlist == NULL)||(t_identlist->next == NULL)
979 ||(t_identlist->next->next == NULL))
980 {
981 printf("Error: Sequence statements must reference > 1 instruments.\n\n");
982 showerrorplace(t_sequence->linenum, t_sequence->filename);
983 }
984 return retptr;
985 }
986
987
988 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
989 /* */
990 /* Top-level functions for statements in instrs or opcodes. */
991 /* */
992 /*______________________________________________________________*/
993
994 /***********************************************************************/
995 /* statement (done): lvalue EQ expr SEM */
996 /* (done)| expr SEM */
997 /* (done)| IF LP expr RP LC block RC */
998 /* (done)| IF LP expr RP LC block RC ELSE LC block RC */
999 /* (done)| WHILE LP expr RP LC block RC */
1000 /* (done)| INSTR IDENT LP exprlist RP SEM */
1001 /* (done)| OUTPUT LP exprlist RP SEM */
1002 /* (done)| SPATIALIZE LP exprlist RP SEM */
1003 /* (done)| OUTBUS LP IDENT COM exprlist RP SEM */
1004 /* (done)| EXTEND LP expr RP SEM */
1005 /* (done)| TURNOFF SEM */
1006 /* (done)| RETURN LP exprlist RP SEM */
1007 /* (done)| PRINTF LP exprstrlist RP SEM */
1008 /* exprlist can be NULL -> t_three,t_four,t_five can be null */
1009 /***********************************************************************/
1010
make_statement(tnode * t_one,tnode * t_two,tnode * t_three,tnode * t_four,tnode * t_five,tnode * t_six,tnode * t_seven,tnode * t_eight,tnode * t_nine,tnode * t_ten,tnode * t_eleven)1011 tnode * make_statement(tnode * t_one, tnode * t_two, tnode * t_three,
1012 tnode * t_four, tnode * t_five, tnode * t_six,
1013 tnode * t_seven, tnode * t_eight, tnode * t_nine,
1014 tnode * t_ten, tnode * t_eleven)
1015 {
1016 tnode * retptr;
1017 tnode * ptr;
1018
1019 retptr = make_tnode("<statement>",S_STATEMENT);
1020
1021 retptr->down = t_one;
1022
1023 if (t_two->ttype == S_SEM) /* expr; and turnoff; statements */
1024 {
1025 t_one->next = t_two;
1026 if (t_one->ttype == S_EXPR) /* expr SEM */
1027 {
1028 tablecheck(t_one);
1029 }
1030 else /* turnoff SEM */
1031 {
1032 }
1033 return retptr;
1034 }
1035
1036
1037
1038 if (t_one->ttype == S_LVALUE) /* lvalue EQ expr SEM */
1039 {
1040 tablecheck(t_three);
1041 t_one->next = t_two;
1042 t_two->next = t_three;
1043 t_three->next = t_four;
1044 t_one->res = ASFLOAT;
1045 return retptr;
1046 }
1047
1048
1049 if ((t_six == NULL)&&(t_seven == NULL))
1050 {
1051 if (t_one->ttype == S_OUTPUT) /* OUTPUT LP exprlist RP SEM */
1052 {
1053 tablelistcheck(t_three);
1054 t_one->next = t_two;
1055 t_two->next = make_tnode("<exprlist>",S_EXPRLIST);
1056 t_two->next->down = t_three;
1057 t_two->next->next = t_four;
1058 t_four->next = t_five;
1059 if (t_three == NULL)
1060 {
1061 printf("Error: Output statements must have width >= 1.\n\n");
1062 showerrorplace(t_one->linenum, t_one->filename);
1063 }
1064 return retptr;
1065
1066 }
1067
1068 if (t_one->ttype == S_RETURN) /* RETURN LP exprlist RP SEM */
1069 {
1070 if (isaninstr == 1)
1071 {
1072 printf("Error: Instrs cannot contain return statements.\n\n");
1073 showerrorplace(t_one->linenum, t_one->filename);
1074 }
1075 tablelistcheck(t_three);
1076 if (t_three == NULL)
1077 {
1078 t_three = make_tnode("<expr>", S_EXPR);
1079 t_three->down = make_tnode("0", S_INTGR);
1080 t_three->res = t_three->down->res = ASINT;
1081 t_three->vol = t_three->down->vol = CONSTANT;
1082 }
1083 t_one->next = t_two;
1084 t_two->next = make_tnode("<exprlist>",S_EXPRLIST);
1085 t_two->next->down = t_three;
1086 t_two->next->next = t_four;
1087 t_four->next = t_five;
1088 return retptr;
1089 }
1090
1091 if (t_one->ttype == S_PRINTF) /* PRINTF LP exprstrlist RP SEM */
1092 {
1093 tablelistcheck(t_three);
1094 t_one->next = t_two;
1095 t_two->next = make_tnode("<exprstrlist>",S_EXPRSTRLIST);
1096 t_two->next->down = t_three;
1097 t_two->next->next = t_four;
1098 t_four->next = t_five;
1099 return retptr;
1100 }
1101
1102 if (t_one->ttype == S_EXTEND) /* EXTEND LP expr RP SEM */
1103 {
1104 tablecheck(t_three);
1105 t_one->next = t_two;
1106 t_two->next = t_three;
1107 t_three->next = t_four;
1108 t_four->next = t_five;
1109 return retptr;
1110 }
1111
1112
1113 if (t_one->ttype == S_SPATIALIZE) /* SPATIALIZE LP exprlist RP SEM */
1114 {
1115 tablelistcheck(t_three);
1116 t_one->next = t_two;
1117 t_two->next = make_tnode("<exprlist>",S_EXPRLIST);
1118 t_two->next->down = t_three;
1119 t_two->next->next = t_four;
1120 t_four->next = t_five;
1121 if (locopcodecalls == NULL)
1122 ptr = locopcodecalls = make_tnode(t_one->val, S_OPCALL);
1123 else
1124 {
1125 ptr = locopcodecalls;
1126 while (ptr->next != NULL)
1127 ptr = ptr->next;
1128 ptr->next = make_tnode(t_one->val, S_OPCALL);
1129 ptr = ptr->next;
1130 }
1131 t_one->optr = retptr->optr = ptr;
1132 ptr->optr = retptr;
1133 return retptr;
1134 }
1135
1136 return NULL;
1137 }
1138
1139
1140 if (t_seven == NULL)
1141 {
1142 /* INSTR IDENT LP exprlist RP SEM */
1143
1144 tablelistcheck(t_four);
1145 t_two->ttype = S_INSTRNAME;
1146 t_one->next = t_two;
1147 t_two->next = t_three;
1148 t_three->next = make_tnode("<exprlist>",S_EXPRLIST);
1149 t_three->next->down = t_four;
1150 t_three->next->next = t_five;
1151 t_five->next = t_six;
1152
1153 if (locdyncalls == NULL)
1154 ptr = locdyncalls = make_tnode(t_two->val, S_INSTR);
1155 else
1156 {
1157 ptr = locdyncalls;
1158 while (ptr->next != NULL)
1159 ptr = ptr->next;
1160 ptr->next =make_tnode(t_two->val, S_INSTR);
1161 ptr = ptr->next;
1162 }
1163 ptr->dptr = retptr;
1164 retptr->dptr = ptr;
1165 return retptr;
1166 }
1167
1168 /* handle IF, WHILE, and OUTBUS here, do linking separately */
1169
1170 if (t_one->ttype == S_IF) /* IF LP expr RP LC block RC */
1171 { /* IF LP expr RP LC block RC ELSE LC block RC */
1172 conditionalblocks++;
1173 tablecheck(t_three);
1174 t_one->next = t_two;
1175 t_two->next = t_three;
1176 t_three->next = t_four;
1177 t_four->next = t_five;
1178 t_five->next = make_tnode("<block>",S_BLOCK);
1179 t_five->next->down = t_six;
1180 t_five->next->next = t_seven;
1181 if (t_eight == NULL)
1182 return retptr;
1183 else /* ELSE */
1184 {
1185 conditionalblocks++;
1186 t_seven->next = t_eight;
1187 t_eight->next = t_nine;
1188 t_nine->next = make_tnode("<block>",S_BLOCK);
1189 t_nine->next->down = t_ten;
1190 t_nine->next->next = t_eleven;
1191 return retptr;
1192 }
1193 }
1194
1195 if (t_one->ttype == S_WHILE) /* WHILE LP expr RP LC block RC */
1196 {
1197 tablecheck(t_three);
1198 t_one->next = t_two;
1199 t_two->next = t_three;
1200 t_three->next = t_four;
1201 t_four->next = t_five;
1202 t_five->next = make_tnode("<block>",S_BLOCK);
1203 t_five->next->down = t_six;
1204 t_five->next->next = t_seven;
1205 return retptr;
1206 }
1207
1208 if (t_one->ttype == S_OUTBUS) /* OUTBUS LP IDENT COM exprlist RP SEM */
1209 {
1210 tablelistcheck(t_five);
1211 t_three->ttype = S_OUTBUSNAME;
1212 t_one->next = t_two;
1213 t_two->next = t_three;
1214 t_three->next = t_four;
1215 t_four->next = make_tnode("<exprlist>",S_EXPRLIST);
1216 t_four->next->down = t_five;
1217 t_four->next->next = t_six;
1218 t_six->next = t_seven;
1219 if (t_five == NULL)
1220 {
1221 printf("Error: Outbus statements must have width >= 1.\n\n");
1222 showerrorplace(t_one->linenum, t_one->filename);
1223 }
1224
1225 /* log outbus statement on outbustable */
1226
1227 ptr = make_tnode(t_three->val, S_BUS);
1228 ptr->down = retptr;
1229 if (outbustable == NULL)
1230 outbustable = ptr;
1231 else
1232 {
1233 ptr->next = outbustable;
1234 outbustable = ptr;
1235 }
1236
1237 return retptr;
1238
1239 }
1240
1241 return NULL; /* should never happen */
1242 }
1243
1244 /***********************************************************************/
1245 /* lvalue : IDENT */
1246 /* | IDENT LB expr RB */
1247 /***********************************************************************/
1248
make_lval(tnode * t_ident,tnode * t_lb,tnode * t_expr,tnode * t_rb)1249 tnode * make_lval(tnode * t_ident, tnode * t_lb, tnode * t_expr,
1250 tnode * t_rb)
1251
1252 {
1253 tnode * retptr;
1254
1255 if (suspendvarchecks == 0)
1256 {
1257 t_ident->sptr = getsym(&locsymtable,t_ident);
1258 if ((t_ident->sptr == NULL) && strcmp(t_ident->val,"MIDIctrl") &&
1259 strcmp(t_ident->val,"params"))
1260 {
1261 printf("Error: Inappropriate lval name %s.\n", t_ident->val);
1262 showerrorplace(t_ident->linenum, t_ident->filename);
1263 }
1264
1265 /* a place to check for faster-rate assignments in poly-ops */
1266 /*
1267 if (t_ident->sptr)
1268 {
1269 switch (t_ident->sptr->rate)
1270 {
1271 case IRATETYPE:
1272 break;
1273 case KRATETYPE:
1274 break;
1275 case ARATETYPE:
1276 break;
1277 case XRATETYPE:
1278 break;
1279 }
1280 }
1281 */
1282
1283 tablecheck(t_ident);
1284 }
1285 retptr = make_tnode("<lvalue>",S_LVALUE);
1286 retptr->down = t_ident;
1287
1288 if (t_ident->sptr != NULL)
1289 {
1290 t_ident->res = t_ident->sptr->res;
1291 t_ident->vartype = t_ident->sptr->vartype;
1292 }
1293 else
1294 {
1295 t_ident->res = standardres(t_ident);
1296 t_ident->vartype = standardvartype(t_ident);
1297 }
1298
1299 if (t_lb == NULL)
1300 {
1301 retptr->res = t_ident->res;
1302 retptr->vartype = t_ident->vartype;
1303 return retptr;
1304 }
1305
1306 /* this section handles indexed arrays*/
1307
1308 t_ident->next = t_lb;
1309 t_lb->next = t_expr;
1310 t_expr->next = t_rb;
1311
1312 if (t_ident->vartype == SCALARTYPE)
1313 {
1314 printf("Error: Using array indexing on a scalar variable.\n\n");
1315 showerrorplace(t_ident->linenum, t_ident->filename);
1316 }
1317
1318 retptr->vartype = SCALARTYPE;
1319 retptr->res = t_ident->res;
1320 tablecheck(t_expr);
1321
1322 return retptr;
1323
1324 }
1325
1326
1327 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1328 /* */
1329 /* Top-level functions for variable declarations. */
1330 /* */
1331 /*______________________________________________________________*/
1332
1333 /***********************************************************************/
1334 /* vardecl : taglist stype namelist SEM */
1335 /* | stype namelist SEM */
1336 /***********************************************************************/
1337
make_simplevar(tnode * t_taglist,tnode * t_type,tnode * t_namelist,tnode * t_sem,char * name,int number)1338 tnode * make_simplevar(tnode * t_taglist, tnode * t_type,
1339 tnode * t_namelist, tnode * t_sem,
1340 char * name, int number)
1341 {
1342 tnode * retptr;
1343 tnode * ptr;
1344 int newkind;
1345 int symstate;
1346 int target;
1347
1348 retptr = make_tnode(name,number);
1349 retptr->rate = t_type->rate;
1350
1351 if (number == S_OPVARDECL)
1352 {
1353 if ((opcodenametable->rate == XRATETYPE) && (!nonpolyparams) &&
1354 ((t_type->ttype == S_KSIG) || (t_type->ttype == S_ASIG)))
1355 {
1356 if (t_type->ttype == S_KSIG)
1357 printf("Error: Poly-opcode ksig declarations restricted.\n\n");
1358 else
1359 printf("Error: Poly-opcode asig declarations restricted.\n\n");
1360 showerrorplace(t_type->linenum, t_type->filename);
1361 }
1362 if ((opcodenametable->rate == IRATETYPE) &&
1363 ((t_type->ttype == S_KSIG) || (t_type->ttype == S_ASIG)))
1364 {
1365 if (t_type->ttype == S_KSIG)
1366 printf("Error: Ksig declarations not allowed in iopcodes.\n\n");
1367 else
1368 printf("Error: Asig declarations not allowed in iopcodes.\n\n");
1369 showerrorplace(t_type->linenum, t_type->filename);
1370 }
1371 if ((opcodenametable->rate == KRATETYPE) && (t_type->ttype == S_ASIG))
1372 {
1373 printf("Error: Asig declarations not allowed in kopcodes.\n\n");
1374 showerrorplace(t_type->linenum, t_type->filename);
1375 }
1376 }
1377 if ((t_type->ttype == S_XSIG) && ((number == S_VARDECL) ||
1378 (opcodenametable->rate != XRATETYPE)))
1379 {
1380 printf("Error: Only polymorphic opcodes can use xsig.\n\n");
1381 showerrorplace(t_type->linenum, t_type->filename);
1382 }
1383 target = 0;
1384 if (t_taglist == NULL)
1385 {
1386 retptr->down = t_type;
1387 newkind = K_NORMAL;
1388 }
1389 else
1390 {
1391 if ((t_type->ttype == S_ASIG)||(t_type->ttype == S_OPARRAY))
1392 {
1393 printf("Error: Import/export tags on %s.\n\n", t_type->val);
1394 showerrorplace(t_type->linenum, t_type->filename);
1395 }
1396 retptr->down = t_taglist;
1397 t_taglist->next = t_type;
1398 if (t_taglist->down->next == NULL)
1399 {
1400 newkind = K_EXPORT;
1401 if (t_taglist->down->ttype == S_IMPORTS)
1402 {
1403 newkind = K_IMPORT;
1404 target = isaninstr;
1405 }
1406 }
1407 else
1408 newkind = K_IMPORTEXPORT;
1409 if ((t_type->ttype == S_TABLE)&&(newkind == K_EXPORT))
1410 {
1411 printf("Error: Wavetable placeholder needs imports tag.\n\n");
1412 showerrorplace(t_type->linenum, t_type->filename);
1413 }
1414 }
1415
1416 if (t_type->ttype == S_OPARRAY)
1417 {
1418 if (t_namelist->next != NULL)
1419 {
1420 printf("Error: Multiple opcode declarations per line.\n\n");
1421 showerrorplace(t_type->linenum, t_type->filename);
1422 }
1423 if (t_namelist->down->next == NULL)
1424 {
1425 printf("Error: Opcode declarations without width.\n\n");
1426 showerrorplace(t_type->linenum, t_type->filename);
1427 }
1428
1429 if (locopcodecalls == NULL)
1430 {
1431 ptr = locopcodecalls = make_tnode(t_namelist->down->val,
1432 S_OPARRAYDECL);
1433 ptr->optr = retptr;
1434 retptr->optr = ptr;
1435 }
1436 else
1437 {
1438 ptr = locopcodecalls;
1439 if ((ptr->ttype == S_OPARRAYDECL) &&
1440 (!strcmp(ptr->val,t_namelist->down->val)))
1441 {
1442 printf("Error: Multiple oparrays for same opcode.\n\n");
1443 showerrorplace(t_type->linenum, t_type->filename);
1444 }
1445 while (ptr->next != NULL)
1446 {
1447 if ((ptr->ttype == S_OPARRAYDECL) &&
1448 (!strcmp(ptr->val,t_namelist->down->val)))
1449 {
1450 printf("Error: Multiple oparrays for same opcode.\n\n");
1451 showerrorplace(t_type->linenum, t_type->filename);
1452 }
1453 ptr = ptr->next;
1454 }
1455 ptr->next = make_tnode(t_namelist->down->val, S_OPARRAYDECL);
1456 ptr = ptr->next;
1457 ptr->optr = retptr;
1458 retptr->optr = ptr;
1459 }
1460
1461 switch (t_namelist->down->next->next->ttype) {
1462 case S_INTGR:
1463 sscanf(t_namelist->down->next->next->val,"%d",&(t_namelist->opwidth));
1464 if (t_namelist->opwidth < 1)
1465 {
1466 printf("Error: Oparray width must be >= 1.\n\n");
1467 showerrorplace(t_type->linenum, t_type->filename);
1468 }
1469 retptr->opwidth = ptr->opwidth = t_namelist->down->opwidth =
1470 t_namelist->opwidth;
1471 break;
1472 case S_INCHANNELS:
1473 retptr->opwidth = ptr->opwidth = t_namelist->down->opwidth =
1474 t_namelist->opwidth = INCHANNELSWIDTH;
1475 break;
1476 case S_OUTCHANNELS:
1477 retptr->opwidth = ptr->opwidth = t_namelist->down->opwidth =
1478 t_namelist->opwidth = OUTCHANNELSWIDTH;
1479 break;
1480 }
1481
1482 t_type->next = t_namelist;
1483 t_namelist->next = t_sem;
1484 return retptr;
1485 }
1486
1487 t_type->next = make_tnode("<namelist>",S_NAMELIST);
1488 t_type->next->next = t_sem;
1489 t_type->next->down = t_namelist;
1490
1491 ptr = t_namelist;
1492 while (ptr != NULL)
1493 {
1494 if (ptr->ttype == S_NAME)
1495 {
1496 reservednames(ptr->down);
1497 symstate = addsym(&locsymtable, ptr->down);
1498 symcheck(symstate, ptr->down);
1499
1500 ptr->sptr = locsymtable;
1501 ptr->down->sptr = locsymtable;
1502
1503 if (ptr->down->next != NULL) /* vector case */
1504 {
1505 ptr->down->vartype = locsymtable->vartype =
1506 ptr->vartype = VECTORTYPE;
1507 switch (ptr->down->next->next->ttype) {
1508 case S_INTGR:
1509 sscanf(ptr->down->next->next->val,"%d",&(ptr->width));
1510 if (ptr->width < 1)
1511 {
1512 printf("Error: Array length must be >= 1.\n\n");
1513 showerrorplace(t_type->linenum, t_type->filename);
1514 }
1515 ptr->down->width = locsymtable->width = ptr->width;
1516 break;
1517 case S_INCHANNELS:
1518 ptr->down->width = locsymtable->width =
1519 ptr->width = INCHANNELSWIDTH;
1520 break;
1521 case S_OUTCHANNELS:
1522 ptr->down->width = locsymtable->width =
1523 ptr->width = OUTCHANNELSWIDTH;
1524 break;
1525 }
1526 }
1527 ptr->rate = ptr->down->rate = locsymtable->rate = t_type->rate;
1528 ptr->sptr->kind = newkind;
1529 if (t_type->ttype == S_TABLE)
1530 ptr->down->vartype = locsymtable->vartype =
1531 ptr->vartype = TABLETYPE;
1532 else
1533 if (target && (ptr->vartype == SCALARTYPE))
1534 addsym(&targetsymtable, ptr->down);
1535 }
1536 ptr = ptr->next;
1537 }
1538
1539 return retptr;
1540 }
1541
1542
1543 /***********************************************************************/
1544 /* tabledecl : TABLE IDENT LP IDENT COM exprstrlist RP */
1545 /***********************************************************************/
1546
make_tabledecl(tnode * t_table,tnode * t_tablename,tnode * t_lp,tnode * t_generator,tnode * t_com,tnode * t_exprstrlist,tnode * t_rp)1547 tnode * make_tabledecl(tnode * t_table, tnode * t_tablename, tnode * t_lp,
1548 tnode * t_generator, tnode * t_com,
1549 tnode * t_exprstrlist, tnode *t_rp)
1550
1551 {
1552
1553 tnode * retptr, * tptr;
1554 int symstate;
1555
1556 retptr = make_tnode("<table>", S_TABLE);
1557 retptr->down = t_table;
1558 t_table->next = t_tablename;
1559 t_tablename->next = t_lp;
1560 t_lp->next = t_generator;
1561 t_generator->next = t_com;
1562 t_com->next = make_tnode("<exprstrlist>",S_EXPRSTRLIST);
1563 t_com->next->down = t_exprstrlist;
1564 t_com->next->next = t_rp;
1565 t_rp->next = make_tnode(";",S_SEM);
1566
1567 if (!wavegeneratorname(t_generator))
1568 {
1569 printf("Error: Invalid generator name %s.\n\n",t_generator->val);
1570 showerrorplace(t_generator->linenum, t_generator->filename);
1571 }
1572
1573 if (strcmp(t_generator->val,"sample"))
1574 {
1575 tptr = t_exprstrlist;
1576 while (tptr)
1577 {
1578 if (tptr->ttype == S_STRCONST)
1579 {
1580 printf("Error: String constant %s in non-sample generator.\n\n",
1581 tptr->val);
1582 showerrorplace(tptr->linenum, tptr->filename);
1583 }
1584 tptr = tptr->next;
1585 }
1586 }
1587
1588 reservednames(t_tablename);
1589
1590 symstate = addsym(&locsymtable, t_tablename);
1591 symcheck(symstate, t_tablename);
1592 locsymtable->defnode = retptr;
1593
1594 t_tablename->sptr = locsymtable;
1595 locsymtable->kind = K_NORMAL;
1596 locsymtable->vartype = TABLETYPE;
1597 locsymtable->rate = IRATETYPE;
1598 locsymtable->width = 1;
1599
1600 return retptr;
1601 }
1602
1603
1604 /***********************************************************************/
1605 /* vardecl : TABLEMAP IDENT LP identlist RP SEM */
1606 /***********************************************************************/
1607
make_tablemap(tnode * t_tablemap,tnode * t_name,tnode * t_lp,tnode * t_identlist,tnode * t_rp,tnode * t_sem)1608 tnode * make_tablemap(tnode * t_tablemap, tnode * t_name, tnode * t_lp,
1609 tnode * t_identlist, tnode * t_rp, tnode * t_sem)
1610
1611 {
1612
1613 tnode * retptr;
1614 int symstate;
1615
1616
1617 if (t_identlist == NULL)
1618 {
1619 printf("Error: Tablemap must use at least one table.\n\n");
1620 showerrorplace(t_identlist->linenum, t_identlist->filename);
1621 }
1622 retptr = make_tnode("<tablemap>", S_TABLEMAP);
1623 retptr->down = t_tablemap;
1624 t_tablemap->next = t_name;
1625 t_name->next = t_lp;
1626 t_lp->next = make_tnode("<identlist>",S_IDENTLIST);
1627 t_lp->next->down = t_identlist;
1628 t_lp->next->next = t_rp;
1629 t_rp->next = t_sem;
1630 reservednames(t_name);
1631
1632 symstate = addsym(&locsymtable, t_name);
1633 symcheck(symstate, t_name);
1634 locsymtable->defnode = retptr;
1635
1636 t_name->sptr = locsymtable;
1637 locsymtable->kind = K_NORMAL;
1638 locsymtable->vartype = TMAPTYPE;
1639 locsymtable->rate = IRATETYPE;
1640 locsymtable->width = 1;
1641
1642 return retptr;
1643 }
1644
1645
1646 /***********************************************************************/
1647 /* paramdecl : otype name */
1648 /* ; */
1649 /***********************************************************************/
1650
make_paramdecl(tnode * t_otype,tnode * t_name)1651 tnode * make_paramdecl(tnode * t_otype, tnode * t_name)
1652
1653 {
1654 tnode * retptr;
1655 int symstate;
1656
1657 retptr = make_tnode("<paramdecl>",S_PARAMDECL);
1658 retptr->down = t_otype;
1659 t_otype->next = t_name;
1660
1661 reservednames(t_name->down);
1662
1663 symstate = addsym(&locsymtable, t_name->down);
1664 symcheck(symstate, t_name->down);
1665 locsymtable->kind = K_PFIELD;
1666 retptr->sptr = t_name->sptr = t_name->down->sptr = locsymtable;
1667
1668 if (t_name->down->next != NULL) /* vector case */
1669 {
1670 retptr->vartype = t_name->down->vartype = locsymtable->vartype =
1671 t_name->vartype = VECTORTYPE;
1672 switch (t_name->down->next->next->ttype) {
1673 case S_INTGR:
1674 sscanf(t_name->down->next->next->val,"%d",&(t_name->width));
1675 if (t_name->width < 1)
1676 {
1677 printf("Error: Array length must be >= 1.\n\n");
1678 showerrorplace(t_name->linenum, t_name->filename);
1679 }
1680 retptr->width = t_name->down->width = locsymtable->width = t_name->width;
1681 break;
1682 case S_INCHANNELS:
1683 retptr->width = t_name->down->width = locsymtable->width =
1684 t_name->width = INCHANNELSWIDTH;
1685 break;
1686 case S_OUTCHANNELS:
1687 retptr->width = t_name->down->width = locsymtable->width =
1688 t_name->width = OUTCHANNELSWIDTH;
1689 break;
1690 }
1691 }
1692
1693
1694 switch (t_otype->ttype) {
1695 case S_IVAR:
1696 locsymtable->rate = retptr->rate = t_name->rate = IRATETYPE;
1697 nonpolyparams = 1;
1698 break;
1699 case S_KSIG:
1700 locsymtable->rate = retptr->rate = t_name->rate = KRATETYPE;
1701 if (locsymtable->rate > opcodenametable->rate)
1702 {
1703 printf("Error: Formal argument faster than opcode rate.\n\n");
1704 showerrorplace(t_otype->linenum, t_otype->filename);
1705 }
1706 nonpolyparams = 1;
1707 break;
1708 case S_ASIG:
1709 locsymtable->rate = retptr->rate = t_name->rate = ARATETYPE;
1710 if (locsymtable->rate > opcodenametable->rate)
1711 {
1712 printf("Error: Formal argument faster than opcode rate.\n\n");
1713 showerrorplace(t_otype->linenum, t_otype->filename);
1714 }
1715 nonpolyparams = 1;
1716 break;
1717 case S_XSIG:
1718 if (opcodenametable->rate != XRATETYPE)
1719 {
1720 printf("Error: Only polymorphic opcodes can use xsig.\n\n");
1721 showerrorplace(t_otype->linenum, t_otype->filename);
1722 }
1723 retptr->sptr->rate = retptr->rate = t_name->rate = XRATETYPE;
1724 break;
1725 case S_TABLE:
1726 retptr->vartype = t_name->down->vartype = locsymtable->vartype =
1727 t_name->vartype = TABLETYPE;
1728 locsymtable->rate = retptr->rate = t_name->rate = IRATETYPE;
1729 break;
1730 default:
1731 printf("Error: Oparray not permitted as opcode formal parameter.\n\n");
1732 showerrorplace(t_otype->linenum, t_otype->filename);
1733 }
1734
1735 return retptr;
1736 }
1737
1738 /***********************************************************************/
1739 /* name : IDENT {$$ = make_name($1,NULL,NULL,NULL);} */
1740 /* | IDENT LB INTGR RB {$$ = make_name($1,$2,$3,$4);} */
1741 /* | IDENT LB INCHANNELS RB {$$ = make_name($1,$2,$3,$4);} */
1742 /* | IDENT LB OUTCHANNELS RB {$$ = make_name($1,$2,$3,$4);} */
1743 /***********************************************************************/
1744
1745
make_name(tnode * t_ident,tnode * t_lb,tnode * t_const,tnode * t_rb)1746 tnode * make_name(tnode * t_ident, tnode * t_lb,
1747 tnode * t_const, tnode *t_rb)
1748
1749
1750 {
1751 tnode * retptr;
1752
1753 retptr = make_tnode("<name>",S_NAME);
1754 retptr->down = t_ident;
1755
1756 if (t_lb != NULL) /* vector case, or oparray */
1757 {
1758 t_ident->next = t_lb;
1759 t_lb->next = t_const;
1760 t_const->next = t_rb;
1761 }
1762
1763 return retptr;
1764 }
1765
1766
1767 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1768 /* */
1769 /* Top-level functions for expressions. */
1770 /* */
1771 /*______________________________________________________________*/
1772
1773 /***********************************************************************/
1774 /*expr (done) : IDENT */
1775 /* (done) | const */
1776 /* (done) | IDENT LB expr RB */
1777 /* treeupdate! | SASBF LP exprlist RP */
1778 /* (done) | IDENT LP exprlist RP */
1779 /* (done) | IDENT LB expr RB LP exprlist RP */
1780 /* (done) | expr Q expr COL expr %prec Q */
1781 /* (done) | expr LEQ expr */
1782 /* (done) | expr GEQ expr */
1783 /* (done) | expr NEQ expr */
1784 /* (done) | expr EQEQ expr */
1785 /* (done) | expr GT expr */
1786 /* (done) | expr LT expr */
1787 /* (done) | expr AND expr */
1788 /* (done) | expr OR expr */
1789 /* (done) | expr PLUS expr */
1790 /* (done) | expr MINUS expr */
1791 /* (done) | expr STAR expr */
1792 /* (done) | expr SLASH expr */
1793 /* (done) | NOT expr %prec UNOT */
1794 /* (done) | MINUS expr %prec UMINUS */
1795 /* (done) | LP expr RP */
1796 /* (generated by parsing) */
1797 /* FLOATCAST LP expr RP (int->float) */
1798 /***********************************************************************/
1799
1800 extern tnode * make_asfloat(tnode *);
1801 extern int exprres(tnode *, tnode *);
1802
make_expr(tnode * t_one,tnode * t_two,tnode * t_three,tnode * t_four,tnode * t_five,tnode * t_six,tnode * t_seven)1803 tnode * make_expr(tnode * t_one, tnode * t_two, tnode * t_three,
1804 tnode * t_four, tnode * t_five, tnode * t_six,
1805 tnode * t_seven)
1806 {
1807 tnode * retptr;
1808 tnode * tptr;
1809
1810 if (t_one->ttype == S_SASBF)
1811 {
1812 printf("Error: Sasbf synthesis not supported.\n\n");
1813 showerrorplace(t_one->linenum, t_one->filename);
1814 }
1815
1816 retptr = make_tnode("<expr>",S_EXPR);
1817 if ((t_one->ttype == S_IDENT) && ( (t_two == NULL) || /* scalar */
1818 ((t_four->ttype == S_RB) && (t_five == NULL)) )) /* array */
1819 {
1820 if (standardname(t_one))
1821 {
1822 hasstandardname(t_one);
1823 t_one->res = standardres(t_one);
1824 t_one->vartype = standardvartype(t_one);
1825 }
1826 else
1827 {
1828 if (suspendvarchecks == 0)
1829 {
1830 t_one->sptr = getsym(&locsymtable,t_one);
1831 if (t_one->sptr == NULL)
1832 {
1833 printf("Error: Variable %s not defined.\n\n",
1834 t_one->val);
1835 showerrorplace(t_one->linenum, t_one->filename);
1836 }
1837 t_one->res = t_one->sptr->res;
1838 t_one->vartype = t_one->sptr->vartype;
1839 }
1840 }
1841 }
1842
1843 retptr->down = t_one;
1844 if (t_two == NULL) /* : IDENT and | const */
1845 {
1846 retptr->res = t_one->res;
1847 retptr->vartype = t_one->vartype;
1848 retptr->vol = t_one->vol;
1849 return retptr;
1850 }
1851 t_one->next = t_two;
1852
1853 if (t_three == NULL) /* unary ops and empty opcode call*/
1854 {
1855 if (t_four != NULL) /* empty opcode or SASBF call */
1856 {
1857 t_two->next = make_tnode("<exprlist>",S_EXPRLIST);
1858 t_two->next->next = t_four;
1859 if (locopcodecalls == NULL)
1860 tptr = locopcodecalls = make_tnode(t_one->val, S_OPCALL);
1861 else
1862 {
1863 tptr = locopcodecalls;
1864 while (tptr->next != NULL)
1865 tptr = tptr->next;
1866 tptr->next = make_tnode(t_one->val, S_OPCALL);
1867 tptr = tptr->next;
1868 }
1869 t_one->optr = retptr->optr = tptr;
1870 tptr->optr = retptr;
1871 if (coreopcodename(t_one))
1872 retptr->res = coreopcodeasint(t_one);
1873 return retptr;
1874 }
1875 tablecheck(t_two);
1876 switch (t_one->ttype) {
1877 case S_MINUS: /* MINUS expr %prec UMINUS */
1878 retptr->res = t_two->res;
1879 break;
1880 case S_NOT: /* NOT expr %prec UNOT */
1881 retptr->res = ASINT;
1882 break;
1883 }
1884 return retptr;
1885 }
1886
1887 t_two->next = t_three;
1888 if (t_four == NULL)
1889 {
1890 switch (t_two->ttype) {
1891 case S_EXPR: /* LP expr RP */
1892 tablecheck(t_two);
1893 retptr->res = t_two->res;
1894 break;
1895 case S_LEQ: case S_GEQ: case S_NEQ: /* float op float -> int */
1896 case S_EQEQ: case S_GT: case S_LT:
1897 case S_AND: case S_OR:
1898 tablecheck(t_one);
1899 tablecheck(t_three);
1900 retptr->res = ASINT;
1901 break;
1902 case S_STAR: /* * */
1903 tablecheck(t_one);
1904 tablecheck(t_three);
1905 retptr->res = exprres(t_one, t_three);
1906 if ((t_one->down != NULL) && (t_one->down->ttype == S_EXPR) &&
1907 (t_one->down->next != NULL) &&
1908 (t_one->down->next->ttype == S_STAR))
1909 {
1910 retptr->down = t_one->down;
1911 tptr = t_one->down;
1912 while (tptr->next != NULL)
1913 tptr = tptr->next;
1914 tptr->next = t_two;
1915 }
1916 if ((t_three->down != NULL) && (t_three->down->ttype == S_EXPR) &&
1917 (t_three->down->next != NULL) &&
1918 (t_three->down->next->ttype == S_STAR))
1919 {
1920 t_two->next = t_three->down;
1921 }
1922 break;
1923 case S_PLUS: case S_MINUS: /* +,- */
1924 tablecheck(t_one);
1925 tablecheck(t_three);
1926 retptr->res = exprres(t_one, t_three);
1927 if ((t_one->down != NULL) && (t_one->down->ttype == S_EXPR) &&
1928 (t_one->down->next != NULL) &&
1929 ((t_one->down->next->ttype == S_PLUS) ||
1930 (t_one->down->next->ttype == S_MINUS)))
1931 {
1932 retptr->down = t_one->down;
1933 tptr = t_one->down;
1934 while (tptr->next != NULL)
1935 tptr = tptr->next;
1936 tptr->next = t_two;
1937 }
1938 if ((t_three->down != NULL) && (t_three->down->ttype == S_EXPR) &&
1939 (t_three->down->next != NULL) &&
1940 ((t_three->down->next->ttype == S_PLUS) ||
1941 (t_three->down->next->ttype == S_MINUS)))
1942 {
1943 t_two->next = t_three->down;
1944 }
1945 break;
1946 case S_SLASH: /* / */
1947 tablecheck(t_one);
1948 tablecheck(t_three);
1949 retptr->res = ASFLOAT;
1950 t_two->next = t_three = make_asfloat(t_three);
1951 break;
1952 }
1953 return retptr;
1954 }
1955
1956
1957 if (t_five == NULL)
1958 {
1959 if (t_two->ttype == S_LB) /* array indexing */
1960 {
1961 tablecheck(t_three);
1962 t_three->next = t_four;
1963 if (suspendvarchecks == 0)
1964 {
1965 if (t_one->vartype == SCALARTYPE)
1966 {
1967 printf("Error: Array index on a scalar variable.\n\n");
1968 showerrorplace(t_one->linenum, t_one->filename);
1969 }
1970 if (t_one->vartype == TABLETYPE)
1971 {
1972 printf("Error: Array index on a table variable.\n\n");
1973 showerrorplace(t_one->linenum, t_one->filename);
1974 }
1975
1976 if (t_one->vartype == TMAPTYPE)
1977 retptr->vartype = TABLETYPE;
1978 else
1979 retptr->vartype = SCALARTYPE;
1980 }
1981 retptr->res = t_one->res;
1982 return retptr;
1983 }
1984
1985 if (t_one->ttype == S_IDENT) /* IDENT LP exprlist RP */
1986 {
1987 t_two->next = make_tnode("<exprlist>",S_EXPRLIST);
1988 t_two->next->down = t_three;
1989 t_two->next->next = t_four;
1990 if (locopcodecalls == NULL)
1991 tptr = locopcodecalls = make_tnode(t_one->val, S_OPCALL);
1992 else
1993 {
1994 tptr = locopcodecalls;
1995 while (tptr->next != NULL)
1996 tptr = tptr->next;
1997 tptr->next = make_tnode(t_one->val, S_OPCALL);
1998 tptr = tptr->next;
1999 }
2000 t_one->optr = retptr->optr = tptr;
2001 tptr->optr = retptr;
2002 if (coreopcodename(t_one))
2003 retptr->res = coreopcodeasint(t_one);
2004 return retptr;
2005 }
2006
2007 /* SASBF */
2008 t_three->next = t_four; /* will need <exprlist> */
2009 return retptr;
2010 }
2011
2012
2013 t_three->next = t_four;
2014 t_four->next = t_five; /* expr Q expr COL expr */
2015 if (t_six == NULL)
2016 {
2017 if (t_seven != NULL) /* zero argument oparray call */
2018 {
2019 tablecheck(t_three);
2020 t_five->next = make_tnode("<exprlist>",S_EXPRLIST);
2021 t_five->next->next = t_seven;
2022
2023 if (locopcodecalls == NULL)
2024 tptr = locopcodecalls = make_tnode(t_one->val, S_OPARRAYCALL);
2025 else
2026 {
2027 tptr = locopcodecalls;
2028 while (tptr->next != NULL)
2029 tptr = tptr->next;
2030 tptr->next = make_tnode(t_one->val, S_OPARRAYCALL);
2031 tptr = tptr->next;
2032 }
2033 t_one->optr = retptr->optr = tptr;
2034 tptr->optr = retptr;
2035
2036 if (suspendvarchecks == 0)
2037 {
2038 tptr = locopcodecalls;
2039 while ((tptr != NULL) && (tptr->ttype == S_OPARRAYDECL) &&
2040 (strcmp(tptr->val,t_one->val) != 0))
2041 tptr = tptr->next;
2042 if ((tptr == NULL) || (tptr->opwidth == 0))
2043 {
2044 printf("Error: Undeclared oparray call %s.\n\n",
2045 t_one->val);
2046 showerrorplace(t_one->linenum, t_one->filename);
2047 }
2048 t_one->optr->ibus = tptr;
2049 }
2050 if (coreopcodename(t_one))
2051 retptr->res = coreopcodeasint(t_one);
2052 return retptr;
2053 }
2054 tablecheck(t_one);
2055 tablecheck(t_three);
2056 tablecheck(t_five);
2057 if ( ((t_three->res == ASINT) && (t_five->res == ASINT)) ||
2058 ((t_three->res == ASFLOAT) && (t_five->res == ASFLOAT)) )
2059 retptr->res = t_three->res;
2060 else
2061 {
2062 retptr->res = ASFLOAT;
2063 switch (t_three->res) {
2064 case ASINT:
2065 t_two->next = make_asfloat(t_three);
2066 t_two->next->next = t_four;
2067 break;
2068 case ASFLOAT:
2069 t_four->next = make_asfloat(t_five);
2070 break;
2071 }
2072 }
2073 return retptr;
2074 }
2075
2076 t_five->next = make_tnode("<exprlist>",S_EXPRLIST);
2077 t_five->next->down = t_six;
2078 t_five->next->next = t_seven;
2079
2080 /* IDENT LB expr RB LP exprlist RP */
2081
2082 tablecheck(t_three);
2083 if (locopcodecalls == NULL)
2084 tptr = locopcodecalls = make_tnode(t_one->val, S_OPARRAYCALL);
2085 else
2086 {
2087 tptr = locopcodecalls;
2088 while (tptr->next != NULL)
2089 tptr = tptr->next;
2090 tptr->next = make_tnode(t_one->val, S_OPARRAYCALL);
2091 tptr = tptr->next;
2092 }
2093 t_one->optr = retptr->optr = tptr;
2094 tptr->optr = retptr;
2095
2096 if (suspendvarchecks == 0)
2097 {
2098 tptr = locopcodecalls;
2099 while ((tptr != NULL) && (tptr->ttype == S_OPARRAYDECL) &&
2100 (strcmp(tptr->val,t_one->val) != 0))
2101 tptr = tptr->next;
2102 if ((tptr == NULL) || (tptr->opwidth == 0))
2103 {
2104 printf("Error: Undeclared oparray call %s.\n\n",
2105 t_one->val);
2106 showerrorplace(t_one->linenum, t_one->filename);
2107 }
2108 t_one->optr->ibus = tptr;
2109 }
2110
2111 if (coreopcodename(t_one))
2112 retptr->res = coreopcodeasint(t_one);
2113
2114 return retptr;
2115
2116 }
2117
2118
2119 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2120 /* */
2121 /* Top-level functions for generic reductions. */
2122 /* */
2123 /*______________________________________________________________*/
2124
2125 /*****************************************************/
2126 /* handles two-element left-recursion tnode building */
2127 /*****************************************************/
2128
leftrecurse(tnode * left,tnode * right)2129 tnode * leftrecurse(tnode * left, tnode * right)
2130
2131 {
2132
2133 tnode * ptr;
2134 tnode * ret;
2135
2136 if (left != NULL)
2137 {
2138 ptr = left;
2139 while (ptr->next != NULL)
2140 ptr = ptr->next;
2141 ptr->next = right;
2142 ret = left;
2143 }
2144 else
2145 ret = right;
2146
2147 return ret;
2148
2149 }
2150
2151 /********************************************************/
2152 /* handles left-recursion tnode building with separation*/
2153 /********************************************************/
2154
leftsrecurse(tnode * left,tnode * middle,tnode * right)2155 tnode * leftsrecurse(tnode * left, tnode * middle, tnode * right)
2156
2157 {
2158
2159 tnode * ptr;
2160 tnode * ret = NULL;
2161
2162 if ((left != NULL)&&(middle != NULL)) /* this should always happen */
2163 {
2164 ptr = left;
2165 while (ptr->next != NULL)
2166 ptr = ptr->next;
2167 ptr->next = middle;
2168 middle->next = right;
2169 ret = left;
2170 }
2171 else
2172 {
2173 if (left == NULL)
2174 {
2175 if (middle == NULL)
2176 ret = right;
2177 else
2178 {
2179 middle->next = right;
2180 ret = middle;
2181 }
2182 }
2183 }
2184
2185 return ret;
2186
2187 }
2188
2189 /*********************************************************************/
2190 /* makes a new subtree, takes upto four tnodes -- NULL unused tnodes */
2191 /*********************************************************************/
2192
make_stree(tnode * t_one,tnode * t_two,tnode * t_three,tnode * t_four,char * name,int number)2193 tnode * make_stree(tnode * t_one, tnode * t_two, tnode * t_three,
2194 tnode * t_four, char * name, int number)
2195
2196
2197 {
2198
2199 tnode * retptr;
2200
2201 retptr = make_tnode(name,number);
2202 retptr->down = t_one;
2203
2204 if (t_one != NULL)
2205 {
2206 t_one->next = t_two;
2207 if (t_two != NULL)
2208 {
2209 t_two->next = t_three;
2210 if (t_three != NULL)
2211 t_three->next = t_four;
2212 }
2213 }
2214 return retptr;
2215
2216 }
2217
2218
2219 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2220 /* */
2221 /* Utility functions specific to a complex reduction above. */
2222 /* */
2223 /*______________________________________________________________*/
2224
2225 /************************************************************/
2226 /* makes expression an ASFLOAT expr: used in make_expr() */
2227 /************************************************************/
2228
make_asfloat(tnode * exprptr)2229 tnode * make_asfloat(tnode * exprptr)
2230
2231 {
2232 tnode * retptr;
2233
2234 if (exprptr->res == ASFLOAT)
2235 return exprptr;
2236
2237 if ( (exprptr->down->ttype == S_INTGR) && (exprptr->down->next == NULL) &&
2238 (exprptr->down->down == NULL))
2239 {
2240 strcat(exprptr->down->val,".0");
2241 exprptr->down->ttype = S_NUMBER;
2242 exprptr->res = exprptr->down->res = ASFLOAT;
2243 return exprptr;
2244 }
2245
2246 retptr = make_stree(make_tnode("(float)",S_FLOATCAST),
2247 make_tnode("(",S_LP), exprptr,
2248 make_tnode(")",S_RP), "<expr>", S_EXPR);
2249
2250 retptr->res = ASFLOAT;
2251 return retptr;
2252 }
2253
2254 /************************************************************/
2255 /* res check for two tnodes in an expr: used in make_expr() */
2256 /************************************************************/
2257
exprres(tnode * left,tnode * right)2258 int exprres(tnode * left, tnode * right)
2259
2260 {
2261 if ((left->res == ASINT) && (right->res == ASINT))
2262 return ASINT;
2263 return ASFLOAT;
2264 }
2265
2266 /************************************************************/
2267 /* checks identifiers for reserved names: in declarations */
2268 /************************************************************/
2269
reservednames(tnode * tptr)2270 void reservednames(tnode * tptr)
2271
2272 {
2273 int badname = 0;
2274
2275 if (standardname(tptr))
2276 {
2277 printf("Error: Standard ");
2278 badname = 1;
2279 }
2280 if (coreopcodename(tptr))
2281 {
2282 printf("Error: Core opcode ");
2283 badname = 1;
2284 }
2285 if (wavegeneratorname(tptr))
2286 {
2287 printf("Error: Core wavetable generator ");
2288 badname = 1;
2289 }
2290 if (badname)
2291 {
2292 printf("name %s used for identifier.\n\n", tptr->val);
2293 showerrorplace(tptr->linenum, tptr->filename);
2294 }
2295 }
2296
2297 extern void exprtableok(tnode * tptr);
2298
2299 /************************************************************/
2300 /* checks table expressions for local variables: top decls */
2301 /************************************************************/
2302
tableexprcheck(void)2303 void tableexprcheck(void)
2304
2305 {
2306
2307 sigsym * sptr = locsymtable;
2308 tnode * tptr;
2309
2310 while (sptr != NULL)
2311 {
2312 if ((sptr->vartype == TABLETYPE) && (sptr->kind == K_NORMAL))
2313 {
2314 tptr = sptr->defnode->down->next->next->next->next->next->down;
2315 while (tptr != NULL)
2316 {
2317 if (tptr->ttype == S_EXPR)
2318 exprtableok(tptr);
2319 tptr = tptr->next;
2320 }
2321 }
2322 sptr = sptr->next;
2323 }
2324 }
2325
2326 /************************************************************/
2327 /* helps check table expressions for local variables: above */
2328 /************************************************************/
2329
exprtableok(tnode * tptr)2330 void exprtableok(tnode * tptr)
2331
2332 {
2333 while (tptr != NULL)
2334 {
2335 if (tptr->down != NULL)
2336 {
2337 exprtableok(tptr->down);
2338 }
2339 else
2340 {
2341 if ((tptr->ttype == S_IDENT) && (tptr->sptr != NULL) &&
2342 (tptr->sptr->kind != K_PFIELD) &&
2343 (! ( ((tptr->sptr->kind == K_IMPORT)||
2344 (tptr->sptr->kind == K_IMPORTEXPORT)) &&
2345 (tptr->sptr->rate == IRATETYPE) ))&&
2346 (tptr->sptr->vartype != TABLETYPE) &&
2347 (tptr->sptr->vartype != TMAPTYPE))
2348 {
2349 printf("Error: Table expr may not use local variable %s.\n\n",
2350 tptr->val);
2351 showerrorplace(tptr->linenum, tptr->filename);
2352 }
2353 }
2354 tptr = tptr->next;
2355 }
2356
2357 }
2358
2359 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
2360 /* */
2361 /* Utility functions also used in other sfront files. */
2362 /* */
2363 /*______________________________________________________________*/
2364
2365 /***********************************************************************/
2366 /* detects table/tablemap variables in bad places */
2367 /***********************************************************************/
2368
tablecheck(tnode * tptr)2369 void tablecheck(tnode * tptr)
2370
2371 {
2372 if ((tptr != NULL) &&
2373 ((tptr->vartype == TABLETYPE) || (tptr->vartype == TMAPTYPE)))
2374 {
2375 if (tptr->down != NULL)
2376 tptr = tptr->down;
2377 printf("Error: Table(map) %s used inappropriately.\n\n", tptr->val);
2378 showerrorplace(tptr->linenum, tptr->filename);
2379 }
2380 }
2381
2382 /***********************************************************************/
2383 /* detects table/tablemap variables in bad places */
2384 /***********************************************************************/
2385
tablelistcheck(tnode * tptr)2386 void tablelistcheck(tnode * tptr)
2387
2388 {
2389 while (tptr != NULL)
2390 {
2391 if ((tptr->vartype == TABLETYPE) || (tptr->vartype == TMAPTYPE))
2392 {
2393 if (tptr->down != NULL)
2394 tptr = tptr->down;
2395 printf("Error: Table(map) %s used inappropriately.\n\n", tptr->val);
2396 showerrorplace(tptr->linenum, tptr->filename);
2397 }
2398 tptr = tptr->next;
2399 }
2400 }
2401