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