1 #include "defs.h" 2 #include "conv.h" 3 4 int badvalue; 5 6 7 /* The following constants are used to check the limits of */ 8 /* conversions. Dmaxword is the largest double precision */ 9 /* number which can be converted to a two-byte integer */ 10 /* without overflow. Dminword is the smallest double */ 11 /* precision value which can be converted to a two-byte */ 12 /* integer without overflow. Dmaxint and dminint are the */ 13 /* analogous values for four-byte integers. */ 14 15 /* short array should be correct for both VAX and TAHOE */ 16 17 LOCAL short dmaxword[] = { 0x47ff, 0xfeff, 0xffff, 0xffff }; /* 32767.5 */ 18 LOCAL short dminword[] = { 0xc800, 0x007f, 0xffff, 0xffff }; /* -32768.499999999999 */ 19 20 LOCAL short dmaxint[] = { 0x4fff, 0xffff, 0xfeff, 0xffff }; /* 2147483647.5 */ 21 LOCAL short dminint[] = { 0xd000, 0x0000, 0x007f, 0xffff }; /* -2147483648.4999999 */ 22 23 LOCAL short dmaxreal[] = { 0x7fff, 0xffff, 0x7fff, 0xffff }; /* 1.7014117838986683e+38 */ 24 LOCAL short dminreal[] = { 0xffff, 0xffff, 0x7fff, 0xffff }; /* -1.7014117838986683e+38 */ 25 26 27 28 /* The routines which follow are used to convert */ 29 /* constants into constants of other types. */ 30 31 LOCAL char * 32 grabbits(len, cp) 33 int len; 34 Constp cp; 35 { 36 37 static char *toobig = "bit value too large"; 38 39 register char *p; 40 register char *bits; 41 register int i; 42 register int k; 43 register int lenb; 44 45 bits = cp->constant.ccp; 46 lenb = cp->vleng->constblock.constant.ci; 47 48 p = (char *) ckalloc(len); 49 50 if (len >= lenb) 51 k = lenb; 52 else 53 { 54 k = len; 55 if ( badvalue == 0 ) 56 { 57 #if (HERE == PDP11 || HERE == VAX) 58 i = len; 59 while ( i < lenb && bits[i] == 0 ) 60 i++; 61 if (i < lenb) 62 badvalue = 1; 63 #else 64 i = lenb - len - 1; 65 while ( i >= 0 && bits[i] == 0) 66 i--; 67 if (i >= 0) 68 badvalue = 1; 69 #endif 70 if (badvalue) 71 warn(toobig); 72 } 73 } 74 75 #if (HERE == PDP11 || HERE == VAX) 76 i = 0; 77 while (i < k) 78 { 79 p[i] = bits[i]; 80 i++; 81 } 82 #else 83 i = lenb; 84 while (k > 0) 85 p[--k] = bits[--i]; 86 #endif 87 88 return (p); 89 } 90 91 92 93 LOCAL char * 94 grabbytes(len, cp) 95 int len; 96 Constp cp; 97 { 98 register char *p; 99 register char *bytes; 100 register int i; 101 register int k; 102 register int lenb; 103 104 bytes = cp->constant.ccp; 105 lenb = cp->vleng->constblock.constant.ci; 106 107 p = (char *) ckalloc(len); 108 109 if (len >= lenb) 110 k = lenb; 111 else 112 k = len; 113 114 i = 0; 115 while (i < k) 116 { 117 p[i] = bytes[i]; 118 i++; 119 } 120 121 while (i < len) 122 p[i++] = BLANK; 123 124 return (p); 125 } 126 127 128 129 LOCAL expptr 130 cshort(cp) 131 Constp cp; 132 { 133 static char *toobig = "data value too large"; 134 static char *reserved = "reserved operand assigned to an integer"; 135 static char *compat1 = "logical datum assigned to an integer variable"; 136 static char *compat2 = "character datum assigned to an integer variable"; 137 138 register expptr p; 139 register short *shortp; 140 register ftnint value; 141 register long *rp; 142 register double *minp; 143 register double *maxp; 144 realvalue x; 145 146 switch (cp->vtype) 147 { 148 case TYBITSTR: 149 shortp = (short *) grabbits(2, cp); 150 p = (expptr) mkconst(TYSHORT); 151 p->constblock.constant.ci = *shortp; 152 free((char *) shortp); 153 break; 154 155 case TYSHORT: 156 p = (expptr) cpexpr(cp); 157 break; 158 159 case TYLONG: 160 value = cp->constant.ci; 161 if (value >= MINWORD && value <= MAXWORD) 162 { 163 p = (expptr) mkconst(TYSHORT); 164 p->constblock.constant.ci = value; 165 } 166 else 167 { 168 if (badvalue <= 1) 169 { 170 badvalue = 2; 171 err(toobig); 172 } 173 p = errnode(); 174 } 175 break; 176 177 case TYREAL: 178 case TYDREAL: 179 case TYCOMPLEX: 180 case TYDCOMPLEX: 181 minp = (double *) dminword; 182 maxp = (double *) dmaxword; 183 rp = (long *) &(cp->constant.cd[0]); 184 x.q.word1 = rp[0]; 185 x.q.word2 = rp[1]; 186 if (x.f.sign == 1 && x.f.exp == 0) 187 { 188 if (badvalue <= 1) 189 { 190 badvalue = 2; 191 err(reserved); 192 } 193 p = errnode(); 194 } 195 else if (x.d >= *minp && x.d <= *maxp) 196 { 197 p = (expptr) mkconst(TYSHORT); 198 p->constblock.constant.ci = x.d; 199 } 200 else 201 { 202 if (badvalue <= 1) 203 { 204 badvalue = 2; 205 err(toobig); 206 } 207 p = errnode(); 208 } 209 break; 210 211 case TYLOGICAL: 212 if (badvalue <= 1) 213 { 214 badvalue = 2; 215 err(compat1); 216 } 217 p = errnode(); 218 break; 219 220 case TYCHAR: 221 if ( !ftn66flag && badvalue == 0 ) 222 { 223 badvalue = 1; 224 warn(compat2); 225 } 226 227 case TYHOLLERITH: 228 shortp = (short *) grabbytes(2, cp); 229 p = (expptr) mkconst(TYSHORT); 230 p->constblock.constant.ci = *shortp; 231 free((char *) shortp); 232 break; 233 234 case TYERROR: 235 p = errnode(); 236 break; 237 } 238 239 return (p); 240 } 241 242 243 244 LOCAL expptr 245 clong(cp) 246 Constp cp; 247 { 248 static char *toobig = "data value too large"; 249 static char *reserved = "reserved operand assigned to an integer"; 250 static char *compat1 = "logical datum assigned to an integer variable"; 251 static char *compat2 = "character datum assigned to an integer variable"; 252 253 register expptr p; 254 register ftnint *longp; 255 register long *rp; 256 register double *minp; 257 register double *maxp; 258 realvalue x; 259 260 switch (cp->vtype) 261 { 262 case TYBITSTR: 263 longp = (ftnint *) grabbits(4, cp); 264 p = (expptr) mkconst(TYLONG); 265 p->constblock.constant.ci = *longp; 266 free((char *) longp); 267 break; 268 269 case TYSHORT: 270 p = (expptr) mkconst(TYLONG); 271 p->constblock.constant.ci = cp->constant.ci; 272 break; 273 274 case TYLONG: 275 p = (expptr) cpexpr(cp); 276 break; 277 278 case TYREAL: 279 case TYDREAL: 280 case TYCOMPLEX: 281 case TYDCOMPLEX: 282 minp = (double *) dminint; 283 maxp = (double *) dmaxint; 284 rp = (long *) &(cp->constant.cd[0]); 285 x.q.word1 = rp[0]; 286 x.q.word2 = rp[1]; 287 if (x.f.sign == 1 && x.f.exp == 0) 288 { 289 if (badvalue <= 1) 290 { 291 badvalue = 2; 292 err(reserved); 293 } 294 p = errnode(); 295 } 296 else if (x.d >= *minp && x.d <= *maxp) 297 { 298 p = (expptr) mkconst(TYLONG); 299 p->constblock.constant.ci = x.d; 300 } 301 else 302 { 303 if (badvalue <= 1) 304 { 305 badvalue = 2; 306 err(toobig); 307 } 308 p = errnode(); 309 } 310 break; 311 312 case TYLOGICAL: 313 if (badvalue <= 1) 314 { 315 badvalue = 2; 316 err(compat1); 317 } 318 p = errnode(); 319 break; 320 321 case TYCHAR: 322 if ( !ftn66flag && badvalue == 0 ) 323 { 324 badvalue = 1; 325 warn(compat2); 326 } 327 328 case TYHOLLERITH: 329 longp = (ftnint *) grabbytes(4, cp); 330 p = (expptr) mkconst(TYLONG); 331 p->constblock.constant.ci = *longp; 332 free((char *) longp); 333 break; 334 335 case TYERROR: 336 p = errnode(); 337 break; 338 } 339 340 return (p); 341 } 342 343 344 345 LOCAL expptr 346 creal(cp) 347 Constp cp; 348 { 349 static char *toobig = "data value too large"; 350 static char *compat1 = "logical datum assigned to a real variable"; 351 static char *compat2 = "character datum assigned to a real variable"; 352 353 register expptr p; 354 register long *longp; 355 register long *rp; 356 register double *minp; 357 register double *maxp; 358 realvalue x; 359 float y; 360 361 switch (cp->vtype) 362 { 363 case TYBITSTR: 364 longp = (long *) grabbits(4, cp); 365 p = (expptr) mkconst(TYREAL); 366 rp = (long *) &(p->constblock.constant.cd[0]); 367 rp[0] = *longp; 368 free((char *) longp); 369 break; 370 371 case TYSHORT: 372 case TYLONG: 373 p = (expptr) mkconst(TYREAL); 374 p->constblock.constant.cd[0] = cp->constant.ci; 375 break; 376 377 case TYREAL: 378 case TYDREAL: 379 case TYCOMPLEX: 380 case TYDCOMPLEX: 381 minp = (double *) dminreal; 382 maxp = (double *) dmaxreal; 383 rp = (long *) &(cp->constant.cd[0]); 384 x.q.word1 = rp[0]; 385 x.q.word2 = rp[1]; 386 if (x.f.sign == 1 && x.f.exp == 0) 387 { 388 p = (expptr) mkconst(TYREAL); 389 rp = (long *) &(p->constblock.constant.cd[0]); 390 rp[0] = x.q.word1; 391 } 392 else if (x.d >= *minp && x.d <= *maxp) 393 { 394 p = (expptr) mkconst(TYREAL); 395 y = x.d; 396 p->constblock.constant.cd[0] = y; 397 } 398 else 399 { 400 if (badvalue <= 1) 401 { 402 badvalue = 2; 403 err(toobig); 404 } 405 p = errnode(); 406 } 407 break; 408 409 case TYLOGICAL: 410 if (badvalue <= 1) 411 { 412 badvalue = 2; 413 err(compat1); 414 } 415 p = errnode(); 416 break; 417 418 case TYCHAR: 419 if ( !ftn66flag && badvalue == 0) 420 { 421 badvalue = 1; 422 warn(compat2); 423 } 424 425 case TYHOLLERITH: 426 longp = (long *) grabbytes(4, cp); 427 p = (expptr) mkconst(TYREAL); 428 rp = (long *) &(p->constblock.constant.cd[0]); 429 rp[0] = *longp; 430 free((char *) longp); 431 break; 432 433 case TYERROR: 434 p = errnode(); 435 break; 436 } 437 438 return (p); 439 } 440 441 442 443 LOCAL expptr 444 cdreal(cp) 445 Constp cp; 446 { 447 static char *compat1 = 448 "logical datum assigned to a double precision variable"; 449 static char *compat2 = 450 "character datum assigned to a double precision variable"; 451 452 register expptr p; 453 register long *longp; 454 register long *rp; 455 456 switch (cp->vtype) 457 { 458 case TYBITSTR: 459 longp = (long *) grabbits(8, cp); 460 p = (expptr) mkconst(TYDREAL); 461 rp = (long *) &(p->constblock.constant.cd[0]); 462 rp[0] = longp[0]; 463 rp[1] = longp[1]; 464 free((char *) longp); 465 break; 466 467 case TYSHORT: 468 case TYLONG: 469 p = (expptr) mkconst(TYDREAL); 470 p->constblock.constant.cd[0] = cp->constant.ci; 471 break; 472 473 case TYREAL: 474 case TYDREAL: 475 case TYCOMPLEX: 476 case TYDCOMPLEX: 477 p = (expptr) mkconst(TYDREAL); 478 longp = (long *) &(cp->constant.cd[0]); 479 rp = (long *) &(p->constblock.constant.cd[0]); 480 rp[0] = longp[0]; 481 rp[1] = longp[1]; 482 break; 483 484 case TYLOGICAL: 485 if (badvalue <= 1) 486 { 487 badvalue = 2; 488 err(compat1); 489 } 490 p = errnode(); 491 break; 492 493 case TYCHAR: 494 if ( !ftn66flag && badvalue == 0 ) 495 { 496 badvalue = 1; 497 warn(compat2); 498 } 499 500 case TYHOLLERITH: 501 longp = (long *) grabbytes(8, cp); 502 p = (expptr) mkconst(TYDREAL); 503 rp = (long *) &(p->constblock.constant.cd[0]); 504 rp[0] = longp[0]; 505 rp[1] = longp[1]; 506 free((char *) longp); 507 break; 508 509 case TYERROR: 510 p = errnode(); 511 break; 512 } 513 514 return (p); 515 } 516 517 518 519 LOCAL expptr 520 ccomplex(cp) 521 Constp cp; 522 { 523 static char *toobig = "data value too large"; 524 static char *compat1 = "logical datum assigned to a complex variable"; 525 static char *compat2 = "character datum assigned to a complex variable"; 526 527 register expptr p; 528 register long *longp; 529 register long *rp; 530 register double *minp; 531 register double *maxp; 532 realvalue re, im; 533 int overflow; 534 float x; 535 536 switch (cp->vtype) 537 { 538 case TYBITSTR: 539 longp = (long *) grabbits(8, cp); 540 p = (expptr) mkconst(TYCOMPLEX); 541 rp = (long *) &(p->constblock.constant.cd[0]); 542 rp[0] = longp[0]; 543 rp[2] = longp[1]; 544 free((char *) longp); 545 break; 546 547 case TYSHORT: 548 case TYLONG: 549 p = (expptr) mkconst(TYCOMPLEX); 550 p->constblock.constant.cd[0] = cp->constant.ci; 551 break; 552 553 case TYREAL: 554 case TYDREAL: 555 case TYCOMPLEX: 556 case TYDCOMPLEX: 557 overflow = 0; 558 minp = (double *) dminreal; 559 maxp = (double *) dmaxreal; 560 rp = (long *) &(cp->constant.cd[0]); 561 re.q.word1 = rp[0]; 562 re.q.word2 = rp[1]; 563 im.q.word1 = rp[2]; 564 im.q.word2 = rp[3]; 565 if (((re.f.sign == 0 || re.f.exp != 0) && 566 (re.d < *minp || re.d > *maxp)) || 567 ((im.f.sign == 0 || re.f.exp != 0) && 568 (im.d < *minp || re.d > *maxp))) 569 { 570 if (badvalue <= 1) 571 { 572 badvalue = 2; 573 err(toobig); 574 } 575 p = errnode(); 576 } 577 else 578 { 579 p = (expptr) mkconst(TYCOMPLEX); 580 if (re.f.sign == 1 && re.f.exp == 0) 581 re.q.word2 = 0; 582 else 583 { 584 x = re.d; 585 re.d = x; 586 } 587 if (im.f.sign == 1 && im.f.exp == 0) 588 im.q.word2 = 0; 589 else 590 { 591 x = im.d; 592 im.d = x; 593 } 594 rp = (long *) &(p->constblock.constant.cd[0]); 595 rp[0] = re.q.word1; 596 rp[1] = re.q.word2; 597 rp[2] = im.q.word1; 598 rp[3] = im.q.word2; 599 } 600 break; 601 602 case TYLOGICAL: 603 if (badvalue <= 1) 604 { 605 badvalue = 2; 606 err(compat1); 607 } 608 break; 609 610 case TYCHAR: 611 if ( !ftn66flag && badvalue == 0) 612 { 613 badvalue = 1; 614 warn(compat2); 615 } 616 617 case TYHOLLERITH: 618 longp = (long *) grabbytes(8, cp); 619 p = (expptr) mkconst(TYCOMPLEX); 620 rp = (long *) &(p->constblock.constant.cd[0]); 621 rp[0] = longp[0]; 622 rp[2] = longp[1]; 623 free((char *) longp); 624 break; 625 626 case TYERROR: 627 p = errnode(); 628 break; 629 } 630 631 return (p); 632 } 633 634 635 636 LOCAL expptr 637 cdcomplex(cp) 638 Constp cp; 639 { 640 static char *compat1 = "logical datum assigned to a complex variable"; 641 static char *compat2 = "character datum assigned to a complex variable"; 642 643 register expptr p; 644 register long *longp; 645 register long *rp; 646 647 switch (cp->vtype) 648 { 649 case TYBITSTR: 650 longp = (long *) grabbits(16, cp); 651 p = (expptr) mkconst(TYDCOMPLEX); 652 rp = (long *) &(p->constblock.constant.cd[0]); 653 rp[0] = longp[0]; 654 rp[1] = longp[1]; 655 rp[2] = longp[2]; 656 rp[3] = longp[3]; 657 free((char *) longp); 658 break; 659 660 case TYSHORT: 661 case TYLONG: 662 p = (expptr) mkconst(TYDCOMPLEX); 663 p->constblock.constant.cd[0] = cp->constant.ci; 664 break; 665 666 case TYREAL: 667 case TYDREAL: 668 case TYCOMPLEX: 669 case TYDCOMPLEX: 670 p = (expptr) mkconst(TYDCOMPLEX); 671 longp = (long *) &(cp->constant.cd[0]); 672 rp = (long *) &(p->constblock.constant.cd[0]); 673 rp[0] = longp[0]; 674 rp[1] = longp[1]; 675 rp[2] = longp[2]; 676 rp[3] = longp[3]; 677 break; 678 679 case TYLOGICAL: 680 if (badvalue <= 1) 681 { 682 badvalue = 2; 683 err(compat1); 684 } 685 p = errnode(); 686 break; 687 688 case TYCHAR: 689 if ( !ftn66flag && badvalue == 0 ) 690 { 691 badvalue = 1; 692 warn(compat2); 693 } 694 695 case TYHOLLERITH: 696 longp = (long *) grabbytes(16, cp); 697 p = (expptr) mkconst(TYDCOMPLEX); 698 rp = (long *) &(p->constblock.constant.cd[0]); 699 rp[0] = longp[0]; 700 rp[1] = longp[1]; 701 rp[2] = longp[2]; 702 rp[3] = longp[3]; 703 free((char *) longp); 704 break; 705 706 case TYERROR: 707 p = errnode(); 708 break; 709 } 710 711 return (p); 712 } 713 714 715 716 LOCAL expptr 717 clogical(cp) 718 Constp cp; 719 { 720 static char *compat1 = "numeric datum assigned to a logical variable"; 721 static char *compat2 = "character datum assigned to a logical variable"; 722 723 register expptr p; 724 register long *longp; 725 register short *shortp; 726 register int size; 727 728 size = typesize[tylogical]; 729 730 switch (cp->vtype) 731 { 732 case TYBITSTR: 733 p = (expptr) mkconst(tylogical); 734 if (tylogical == TYSHORT) 735 { 736 shortp = (short *) grabbits(size, cp); 737 p->constblock.constant.ci = (int) *shortp; 738 free((char *) shortp); 739 } 740 else 741 { 742 longp = (long *) grabbits(size, cp); 743 p->constblock.constant.ci = *longp; 744 free((char *) longp); 745 } 746 break; 747 748 case TYSHORT: 749 case TYLONG: 750 case TYREAL: 751 case TYDREAL: 752 case TYCOMPLEX: 753 case TYDCOMPLEX: 754 if (badvalue <= 1) 755 { 756 badvalue = 2; 757 err(compat1); 758 } 759 p = errnode(); 760 break; 761 762 case TYLOGICAL: 763 p = (expptr) cpexpr(cp); 764 p->constblock.vtype = tylogical; 765 break; 766 767 case TYCHAR: 768 if ( !ftn66flag && badvalue == 0 ) 769 { 770 badvalue = 1; 771 warn(compat2); 772 } 773 774 case TYHOLLERITH: 775 p = (expptr) mkconst(tylogical); 776 if (tylogical == TYSHORT) 777 { 778 shortp = (short *) grabbytes(size, cp); 779 p->constblock.constant.ci = (int) *shortp; 780 free((char *) shortp); 781 } 782 else 783 { 784 longp = (long *) grabbytes(4, cp); 785 p->constblock.constant.ci = *longp; 786 free((char *) longp); 787 } 788 break; 789 790 case TYERROR: 791 p = errnode(); 792 break; 793 } 794 795 return (p); 796 } 797 798 799 800 LOCAL expptr 801 cchar(len, cp) 802 int len; 803 Constp cp; 804 { 805 static char *compat1 = "numeric datum assigned to a character variable"; 806 static char *compat2 = "logical datum assigned to a character variable"; 807 808 register expptr p; 809 register char *value; 810 811 switch (cp->vtype) 812 { 813 case TYBITSTR: 814 value = grabbits(len, cp); 815 p = (expptr) mkstrcon(len, value); 816 free(value); 817 break; 818 819 case TYSHORT: 820 case TYLONG: 821 case TYREAL: 822 case TYDREAL: 823 case TYCOMPLEX: 824 case TYDCOMPLEX: 825 if (badvalue <= 1) 826 { 827 badvalue = 2; 828 err(compat1); 829 } 830 p = errnode(); 831 break; 832 833 case TYLOGICAL: 834 if (badvalue <= 1) 835 { 836 badvalue = 2; 837 err(compat2); 838 } 839 p = errnode(); 840 break; 841 842 case TYCHAR: 843 case TYHOLLERITH: 844 value = grabbytes(len, cp); 845 p = (expptr) mkstrcon(len, value); 846 free(value); 847 break; 848 849 case TYERROR: 850 p = errnode(); 851 break; 852 } 853 854 return (p); 855 } 856 857 858 859 expptr 860 convconst(type, len, constant) 861 int type; 862 int len; 863 Constp constant; 864 { 865 register expptr p; 866 867 switch (type) 868 { 869 case TYSHORT: 870 p = cshort(constant); 871 break; 872 873 case TYLONG: 874 p = clong(constant); 875 break; 876 877 case TYREAL: 878 p = creal(constant); 879 break; 880 881 case TYDREAL: 882 p = cdreal(constant); 883 break; 884 885 case TYCOMPLEX: 886 p = ccomplex(constant); 887 break; 888 889 case TYDCOMPLEX: 890 p = cdcomplex(constant); 891 break; 892 893 case TYLOGICAL: 894 p = clogical(constant); 895 break; 896 897 case TYCHAR: 898 p = cchar(len, constant); 899 break; 900 901 case TYERROR: 902 case TYUNKNOWN: 903 p = errnode(); 904 break; 905 906 default: 907 badtype("convconst", type); 908 } 909 910 return (p); 911 } 912