1 
2 /*
3 #    Sfront, a SAOL to C translator
4 #    This file: Library for sigsym and tnode structs
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 
41 #include "tree.h"
42 
43 /***************************************/
44 /* simple operations on symbol tables  */
45 /***************************************/
46 
47 /****************************************************************************/
48 /* adds an IDENT idnode to top of symboltable table, checks for duplication */
49 /****************************************************************************/
50 
51 int addsym(sigsym ** table, tnode * idnode)
52 
53 {
54 
55   sigsym* tmp;
56 
57   if (idnode->ttype != S_IDENT)
58     return SYSERROR1;
59 
60   tmp = *table;
61   while (tmp != NULL)
62     {
63       if (!strcmp(tmp->val,idnode->val))
64 	return DUPLICATE;
65       else
66 	tmp = tmp->next;
67     }
68   vmcheck(tmp = (sigsym*) malloc(sizeof(sigsym)));
69 
70   tmp->val = dupval(idnode->val);
71   tmp->rate = idnode->rate;
72   tmp->special = idnode->special;
73   tmp->width = idnode->width;
74   tmp->res = idnode->res;
75   tmp->kind = K_NORMAL;
76   tmp->vartype = SCALARTYPE;
77   tmp->vol = VARIABLE;
78   tmp->defnode = idnode;
79   tmp->next = *table;
80   tmp->numinst = 0;
81   tmp->obus = NULL;
82   tmp->maxifstate = 0;
83   tmp->effects = 0;
84   tmp->score = 0;
85   tmp->ascore = 0;
86   tmp->midi = 0;
87   tmp->amidi = 0;
88   tmp->miditag = 0;
89   tmp->dyn = 0;
90   tmp->startup = 0;
91   tmp->calrate = UNKNOWN;
92   tmp->cref = NULL;
93   tmp->tref = NULL;
94 
95   (*table) = tmp;
96   return INSTALLED;
97 }
98 
99 /****************************************************************************/
100 /* adds a tnode-less symbol to the top of the symbol table                  */
101 /****************************************************************************/
102 
103 int addvsym(sigsym ** table, char * name, int kind)
104 
105 {
106 
107   sigsym* tmp;
108 
109   tmp = *table;
110   while (tmp != NULL)
111     {
112       if (!strcmp(tmp->val, name))
113 	return DUPLICATE;
114       else
115 	tmp = tmp->next;
116     }
117 
118   vmcheck(tmp = (sigsym*) malloc(sizeof(sigsym)));
119 
120   tmp->val = dupval(name);
121   tmp->rate = UNKNOWN;
122   tmp->special = 0;
123   tmp->width = 1;
124   tmp->res = UNKNOWN;
125   tmp->kind = kind;
126   tmp->vartype = SCALARTYPE;
127   tmp->vol = VARIABLE;
128   tmp->defnode = NULL;
129   tmp->next = *table;
130   tmp->numinst = 0;
131   tmp->obus = NULL;
132   tmp->maxifstate = 0;
133   tmp->effects = 0;
134   tmp->score = 0;
135   tmp->midi = 0;
136   tmp->ascore = 0;
137   tmp->amidi = 0;
138   tmp->miditag = 0;
139   tmp->dyn = 0;
140   tmp->startup = 0;
141   tmp->calrate = UNKNOWN;
142   tmp->cref = NULL;
143   tmp->tref = NULL;
144 
145   (*table) = tmp;
146   return INSTALLED;
147 }
148 
149 /****************************************************************************/
150 /* adds a tnode-less symbol to the end of the symbol table                  */
151 /****************************************************************************/
152 
153 sigsym * addvsymend(sigsym ** table, char * name, int kind)
154 
155 {
156 
157   sigsym* tmp;
158   sigsym* last = NULL;
159 
160   tmp = *table;
161   while (tmp != NULL)
162     {
163       if (!strcmp(tmp->val, name))
164 	return tmp;
165       else
166 	{
167 	  last = tmp;
168 	  tmp = tmp->next;
169 	}
170     }
171 
172   vmcheck(tmp = (sigsym*) malloc(sizeof(sigsym)));
173 
174   tmp->val = dupval(name);
175   tmp->rate = UNKNOWN;
176   tmp->special = 0;
177   tmp->width = 1;
178   tmp->res = UNKNOWN;
179   tmp->kind = kind;
180   tmp->vartype = SCALARTYPE;
181   tmp->vol = VARIABLE;
182   tmp->defnode = NULL;
183   tmp->next = NULL;
184   tmp->numinst = 0;
185   tmp->obus = NULL;
186   tmp->maxifstate = 0;
187   tmp->effects = 0;
188   tmp->score = 0;
189   tmp->midi = 0;
190   tmp->ascore = 0;
191   tmp->amidi = 0;
192   tmp->miditag = 0;
193   tmp->dyn = 0;
194   tmp->startup = 0;
195   tmp->calrate = UNKNOWN;
196   tmp->cref = NULL;
197   tmp->tref = NULL;
198 
199   if ((*table) == NULL)
200     (*table) = tmp;
201   else
202     last->next = tmp;
203 
204   return tmp;
205 }
206 
207 /****************************************************************************/
208 /* adds a tnode-less symbol to the symbol table so table is sorted by width */
209 /****************************************************************************/
210 
211 int addvsymsort(sigsym ** table, char * name, int kind)
212 
213 {
214 
215   sigsym * tmp;
216   sigsym * place = NULL;
217   int val;
218 
219   val = atoi(name);
220   tmp = *table;
221   while (tmp != NULL)
222     {
223       if (val == tmp->width)
224 	return DUPLICATE;
225       else
226 	{
227 	  if (tmp->width < val)
228 	    place = tmp;
229 	  tmp = tmp->next;
230 	}
231     }
232 
233   vmcheck(tmp = (sigsym*) malloc(sizeof(sigsym)));
234 
235   tmp->val = dupval(name);
236   tmp->rate = UNKNOWN;
237   tmp->special = 0;
238   tmp->width = val;
239   tmp->res = UNKNOWN;
240   tmp->kind = kind;
241   tmp->vartype = SCALARTYPE;
242   tmp->vol = VARIABLE;
243   tmp->defnode = NULL;
244   tmp->numinst = 0;
245   tmp->obus = NULL;
246   tmp->maxifstate = 0;
247   tmp->effects = 0;
248   tmp->score = 0;
249   tmp->midi = 0;
250   tmp->ascore = 0;
251   tmp->amidi = 0;
252   tmp->miditag = 0;
253   tmp->dyn = 0;
254   tmp->startup = 0;
255   tmp->calrate = UNKNOWN;
256   tmp->cref = NULL;
257   tmp->tref = NULL;
258 
259   if (((*table) == NULL) || (place == NULL))
260     {
261       tmp->next = *table;
262       (*table) = tmp;
263     }
264   else
265     {
266       tmp->next = place->next;
267       place->next = tmp;
268     }
269 
270   return INSTALLED;
271 }
272 
273 /****************************************************************************/
274 /* returns a symbol to the table, given an S_IDENT tnode                    */
275 /****************************************************************************/
276 
277 sigsym * getsym(sigsym ** table, tnode * idnode)
278 
279 {
280 
281   sigsym* tmp;
282   int foundit = 0;
283 
284   if (idnode->ttype != S_IDENT)
285     return NULL;
286 
287   tmp = *table;
288   while ((tmp != NULL) && (!foundit))
289     {
290       if (!strcmp(tmp->val,idnode->val))
291 	foundit = 1;
292       else
293 	tmp = tmp->next;
294     }
295   if (foundit)
296     return tmp;
297   return NULL;
298 
299 }
300 
301 /****************************************************************************/
302 /* returns a symbol to the table, given a name                              */
303 /****************************************************************************/
304 
305 sigsym * getvsym(sigsym ** table, char *  name)
306 
307 {
308 
309   sigsym* tmp = *table;
310   int foundit = 0;
311 
312   while ((tmp != NULL) && (!foundit))
313     {
314       if (!strcmp(tmp->val, name))
315 	foundit = 1;
316       else
317 	tmp = tmp->next;
318     }
319   if (foundit)
320     return tmp;
321   return NULL;
322 
323 }
324 
325 
326 /****************************************************************************/
327 /* aborts program on error                                                  */
328 /****************************************************************************/
329 
330 void symcheck(int symstate, tnode * tsym)
331 
332 
333 {
334   if (symstate == DUPLICATE)
335     {
336       if (tsym != NULL)
337 	{
338 	  printf("Error: Duplicate symbol %s\n", tsym->val);
339 	  showerrorplace(tsym->linenum, tsym->filename);
340 	}
341       else
342 	internalerror("sigsym.c","symcheck() -- Error 1");
343     }
344   if (symstate == SYSERROR1)
345     internalerror("sigsym.c","symcheck() -- Error 2");
346 
347   if (symstate == NOTPRESENT)
348     internalerror("sigsym.c","symcheck() -- Error 3");
349 
350 }
351 
352 /****************************************************************************/
353 /* deletes node from symboltable  */
354 /****************************************************************************/
355 
356 int deletesym(sigsym ** table,sigsym * symnode)
357 
358 {
359 
360   sigsym * tptr;
361 
362   tptr = *table;
363 
364   if ((tptr == NULL)||(symnode == NULL))
365     return NOTPRESENT;
366 
367   if (tptr == symnode)
368     {
369       *table = symnode->next;
370       return DELETED;
371     }
372 
373   while ((tptr->next != symnode) && (tptr->next != NULL))
374     tptr = tptr->next;
375 
376   if (tptr->next == NULL)
377     return NOTPRESENT;
378 
379   tptr->next = symnode->next;
380   return DELETED;
381 
382 }
383 
384 /****************************************************************************/
385 /*               reverse order of sigsym list                               */
386 /****************************************************************************/
387 
388 sigsym * reversetable(sigsym * sptr)
389 
390 
391 {
392 
393   sigsym* retptr = NULL;
394   sigsym* cptr;
395 
396   while (sptr != NULL)
397     {
398       if (retptr == NULL)
399 	{
400 	  retptr = sptr;
401 	  sptr = sptr->next;
402 	  retptr->next = NULL;
403 	}
404       else
405 	{
406 	  cptr = sptr;
407 	  sptr = sptr->next;
408 	  cptr->next = retptr;
409 	  retptr = cptr;
410 	}
411     }
412   return retptr;
413 
414 }
415 
416 /****************************************************************************/
417 /* these routines special-purpose, for instr reordering                     */
418 /****************************************************************************/
419 
420 /****************************************************************************/
421 /* find symbol-table position of last-occuring instr on ilist               */
422 /****************************************************************************/
423 
424 sigsym * findlast(sigsym ** table, tnode * ilist)
425 
426 
427 {
428 
429   tnode * tptr = ilist;
430   sigsym * lastptr = NULL;
431   sigsym * iptr;
432   sigsym * target;
433   int after;
434 
435   while (tptr != NULL)
436     {
437       if (tptr->ttype == S_IDENT)  /* an instrument */
438 	{
439 	  target = getsym(table,tptr);
440 	  iptr = *table;
441 	  after = 0;
442 	  while (iptr != target)
443 	    {
444 	      if (iptr == lastptr)
445 		after = 1;
446 	      iptr = iptr->next;
447 	    }
448 	  if ((after)||(lastptr == NULL))
449 	    {
450 	      lastptr = target;
451 	    }
452 	}
453       tptr = tptr->next;
454     }
455   return lastptr;
456 
457 }
458 
459 /****************************************************************************/
460 /* reorder two elements in the list if necessary                            */
461 /****************************************************************************/
462 
463 void moveafter(sigsym ** table, sigsym * putthis,
464 	       sigsym * afterthis)
465 
466 {
467 
468   sigsym * iptr = *table;
469 
470   if (putthis == afterthis)
471     return;
472 
473   if (iptr == putthis)
474     {
475       *table = putthis->next;
476       putthis->next = afterthis->next;
477       afterthis->next = putthis;
478       return;
479     }
480 
481   while (iptr != afterthis)
482     {
483       if (iptr->next == putthis)
484 	{
485 	  iptr->next = iptr->next->next;
486 	  putthis->next = afterthis->next;
487 	  afterthis->next = putthis;
488 	  return;
489 	}
490       iptr = iptr->next;
491     }
492   return;
493 
494 
495 }
496 
497 
498 /****************************************************************************/
499 /* reorder two elements in the list if necessary                            */
500 /****************************************************************************/
501 
502 int movebefore(sigsym ** table, sigsym * putthis, sigsym * beforethis)
503 
504 {
505 
506   sigsym * iptr = *table;
507   sigsym * placeforit = NULL;
508 
509   while ((iptr != beforethis)&&(iptr != NULL))
510     {
511       if (iptr == putthis)
512 	return 0;
513       placeforit = iptr;
514       iptr = iptr->next;
515     }
516   if (iptr == NULL)
517     return 0;
518   while ((iptr->next != putthis)&&(iptr != NULL))
519     iptr = iptr->next;
520 
521   iptr->next = putthis->next;
522 
523   if (placeforit != NULL)
524     {
525       placeforit->next = putthis;
526       putthis->next = beforethis;
527     }
528   else
529     {
530       putthis->next = beforethis;
531       *table = putthis;
532     }
533   return 1;
534 }
535 
536 
537 /*****************************************************/
538 /* strdup not ANSI -- rewritten with different name  */
539 /*****************************************************/
540 
541 char * dupval(char * val)
542 
543 {
544   char * cpy;
545 
546   if (val)
547     {
548       vmcheck(cpy = (char *) calloc((strlen(val)+1),sizeof(char)));
549       return strcpy(cpy, val);
550     }
551   else
552     return NULL;
553 
554 }
555 
556 /*****************************************************/
557 /* returns string with underscores postpended        */
558 /*****************************************************/
559 
560 char * dupunderscore(char * val)
561 
562 {
563   char * cpy;
564   char * pp = "___";
565 
566   if (val)
567     {
568       vmcheck(cpy = (char *) calloc((strlen(val)+strlen(pp)+1),sizeof(char)));
569       strcpy(cpy, val);
570       return strcat(cpy, pp);
571     }
572   else
573     return NULL;
574 
575 }
576 
577 /********************************************************/
578 /*               makes a new tnode                      */
579 /********************************************************/
580 
581 tnode * make_tnode(char * name, int number)
582 
583 {
584 
585   tnode * retptr;
586 
587   vmcheck(retptr = (tnode *) malloc(sizeof(tnode)));
588 
589   retptr->val = name;
590 
591   retptr->ttype = number;
592   retptr->rate = UNKNOWN;
593   retptr->special = 0;
594   retptr->width = 1;
595   retptr->res = ASFLOAT;
596   retptr->vartype = SCALARTYPE;
597   retptr->vol = VARIABLE;
598 
599   retptr->sptr = NULL;
600   retptr->optr = NULL;
601   retptr->dptr = NULL;
602   retptr->opwidth = 0;
603   retptr->staterate = UNKNOWN;
604   retptr->extra = NULL;
605   retptr->extrarate = UNKNOWN;
606 
607   retptr->ibus = NULL;
608   retptr->arrayidx = 0;
609   retptr->usesinput = 0;
610   retptr->usesingroup = 0;
611   retptr->time = 0;
612   retptr->inwidth = 0;
613 
614   retptr->next = NULL;
615   retptr->down = NULL;
616   retptr->linenum = 0;
617   retptr->filename = NULL;
618 
619   return retptr;
620 }
621 
622 /********************************************************/
623 /*       converts string constant to signed int         */
624 /********************************************************/
625 
626 int make_int(tnode * tptr)
627 
628 {
629   float f;
630 
631   if (tptr->ttype == S_NUMBER)
632     {
633       f = ((float)atof(tptr->val));
634       if (tptr->val[0] != '-')
635 	return (f < ((float)(INT_MAX))) ? ((int)(f + 0.5F)) : INT_MAX;
636       else
637 	return (f > ((float)(INT_MIN))) ? ((int)(f - 0.5F)) : INT_MIN;
638     }
639   return (int) atoi(tptr->val);
640 }
641 
642 /********************************************************/
643 /*   checks if integer is too large for signed 32 bits  */
644 /********************************************************/
645 
646 int largeinteger(char * s)
647 
648 {
649   return ((s[0] != '-') && (strlen(s) == 10) && (strcmp(s, "2147483647") > 0));
650 }
651 
652 /*******************************************************************/
653 /*   determines if an instr is reachable, including effects        */
654 /*******************************************************************/
655 
656 int reachableinstr(sigsym * iptr)
657 
658 {
659   int ret;
660 
661   ret = ((iptr->score) || (iptr->ascore) || (iptr->dyn) || (iptr->effects) ||
662 	 (iptr->startup) || (iptr->midi) || (iptr->amidi) ||
663 	 ((cmidi || session) && iptr->miditag) || csasl);
664   return ret;
665 }
666 
667 /*******************************************************************/
668 /*   determines if an instr is reachable, excepting effects        */
669 /*******************************************************************/
670 
671 int reachableinstrexeff(sigsym * iptr)
672 
673 {
674   int ret;
675 
676   ret = ((iptr->score) || (iptr->ascore) || (iptr->dyn) ||
677 	 (iptr->startup) || (iptr->midi) || (iptr->amidi) ||
678 	 ((cmidi || session) && iptr->miditag) || csasl);
679   return ret;
680 }
681 
682 /*********************************************************/
683 /*   determines if an instr is reachable, except startup */
684 /*********************************************************/
685 
686 int reachableinstrexstart(sigsym * iptr)
687 
688 {
689   int ret;
690 
691   ret = ((iptr->score) || (iptr->ascore) || (iptr->dyn) ||
692 	 (iptr->midi) || (iptr->amidi) || (iptr->effects) ||
693 	 ((cmidi || session) && iptr->miditag) || csasl);
694   return ret;
695 }
696 
697 /*******************************************************************/
698 /*   determines if an instr is reachable, except effects & startup */
699 /*******************************************************************/
700 
701 int reachableinstrexeffexstart(sigsym * iptr)
702 
703 {
704   int ret;
705 
706   ret = ((iptr->score) || (iptr->ascore) || (iptr->dyn) ||
707 	 (iptr->midi) || (iptr->amidi) ||
708 	 ((cmidi || session) && iptr->miditag) || csasl);
709   return ret;
710 }
711 
712 
713