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