dc.c (31359B)
1 #include <assert.h> 2 #include <errno.h> 3 #include <ctype.h> 4 #include <setjmp.h> 5 #include <stdarg.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <limits.h> 10 11 #include "arg.h" 12 #include "util.h" 13 14 #define NDIGITS 10 15 #define REGSIZ 16 16 #define HASHSIZ 128 17 18 enum { 19 NVAL, 20 STR, 21 NUM, 22 }; 23 24 enum { 25 NE, 26 LE, 27 GE, 28 }; 29 30 typedef struct num Num; 31 typedef struct val Val; 32 33 struct num { 34 int begin; 35 int scale; 36 int room; 37 signed char *buf, *wp, *rp; 38 }; 39 40 struct digit { 41 int val; 42 struct digit *next; 43 }; 44 45 struct val { 46 int type; 47 union { 48 Num *n; 49 char *s; 50 } u; 51 52 struct val *next; 53 }; 54 55 struct ary { 56 int n; 57 Val *buf; 58 struct ary *next; 59 }; 60 61 struct reg { 62 char *name; 63 Val val; 64 struct ary ary; 65 struct reg *next; 66 }; 67 68 struct input { 69 FILE *fp; 70 char *buf; 71 size_t n; 72 char *s; 73 struct input *next; 74 }; 75 76 static Val *stack; 77 static jmp_buf env; 78 static struct input *input; 79 static struct reg *htbl[HASHSIZ]; 80 81 static signed char onestr[] = {1, 0}; 82 static Num zero, one = {.buf = onestr, .wp = onestr + 1}; 83 static char digits[] = "0123456789ABCDEF."; 84 85 static int scale, ibase = 10, obase = 10; 86 static int iflag; 87 static int col; 88 89 /* 90 * This dc implementation follows the decription of dc found in the paper 91 * DC - An Interactive Desk Calculator, by Robert Morris and Lorinda Cherry 92 */ 93 94 static void 95 dumpnum(char *msg, Num *num) 96 { 97 signed char *p; 98 99 printf("Num (%s)", msg ? msg : ""); 100 101 if (!num) { 102 puts("NULL\n"); 103 return; 104 } 105 printf("\n" 106 "\tscale=%d\n" 107 "\troom=%d\n" 108 "\tdigits=[\n", 109 num->scale, 110 num->room); 111 for (p = num->buf; p < num->wp; ++p) 112 printf("\t\t%02d\n", *p); 113 printf("\t]\n"); 114 } 115 116 /* 117 * error is not called from the implementation of the 118 * arithmetic functions because that can drive to memory 119 * leaks very easily. 120 */ 121 static void 122 error(char *fmt, ...) 123 { 124 va_list va; 125 126 va_start(va, fmt); 127 xvprintf(fmt, va); 128 putc('\n', stderr); 129 va_end(va); 130 131 longjmp(env, 1); 132 } 133 134 static void 135 freenum(Num *num) 136 { 137 if (!num) 138 return; 139 free(num->buf); 140 free(num); 141 } 142 143 static Num * 144 moreroom(Num *num, int more) 145 { 146 int ro, wo, room; 147 signed char *p; 148 149 ro = num->rp - num->buf; 150 wo = num->wp - num->buf; 151 room = num->room; 152 153 if (room > INT_MAX - more) 154 eprintf("out of memory\n"); 155 156 room = room + more; 157 if (room < NDIGITS) 158 room = NDIGITS; 159 p = erealloc(num->buf, room); 160 num->buf = p; 161 num->rp = p + ro; 162 num->wp = p + wo; 163 num->room = room; 164 165 return num; 166 } 167 168 static Num * 169 grow(Num *num) 170 { 171 return moreroom(num, NDIGITS); 172 } 173 174 static Num * 175 expand(Num *num, int min) 176 { 177 if (min < num->room) 178 return num; 179 return moreroom(num, min - num->room); 180 } 181 182 static Num * 183 new(int room) 184 { 185 Num *num = emalloc(sizeof(*num)); 186 187 num->rp = num->wp = num->buf = NULL; 188 num->begin = num->room = num->scale = 0; 189 190 return moreroom(num, room); 191 } 192 193 static Num * 194 zeronum(int ndigits) 195 { 196 Num *num = new(ndigits); 197 198 num->wp = num->buf + ndigits; 199 memset(num->buf, 0, ndigits); 200 201 return num; 202 } 203 204 static Num * 205 wrdigit(Num *num, int d) 206 { 207 if (num->wp == &num->buf[num->room]) 208 grow(num); 209 *num->wp++ = d; 210 211 return num; 212 } 213 214 static int 215 rddigit(Num *num) 216 { 217 if (num->rp == num->wp) 218 return -1; 219 return *num->rp++; 220 } 221 222 static int 223 peek(Num *num) 224 { 225 if (num->rp == num->wp) 226 return -1; 227 return *num->rp; 228 } 229 230 static Num * 231 poke(Num *num, unsigned d) 232 { 233 if (num->rp == &num->buf[num->room]) 234 grow(num); 235 if (num->rp == num->wp) 236 num->wp++; 237 *num->rp = d; 238 239 return num; 240 } 241 242 static int 243 begin(Num *num) 244 { 245 return num->begin != 0; 246 } 247 248 static int 249 first(Num *num) 250 { 251 num->begin = 0; 252 num->rp = num->buf; 253 return num->rp != num->wp; 254 } 255 256 static int 257 last(Num *num) 258 { 259 if (num->wp != num->buf) { 260 num->begin = 0; 261 num->rp = num->wp - 1; 262 return 1; 263 } 264 num->begin = 1; 265 return 0; 266 } 267 268 static int 269 prev(Num *num) 270 { 271 if (num->rp > num->buf) { 272 --num->rp; 273 return 1; 274 } 275 num->begin = 1; 276 return 0; 277 } 278 279 static int 280 next(Num *num) 281 { 282 if (num->rp != num->wp + 1) { 283 ++num->rp; 284 return 1; 285 } 286 return 0; 287 } 288 289 static void 290 numtrunc(Num *num) 291 { 292 num->wp = num->rp; 293 if (num->rp != num->buf) 294 num->rp--; 295 } 296 297 static int 298 more(Num *num) 299 { 300 return (num->rp != num->wp); 301 } 302 303 static int 304 length(Num *num) 305 { 306 return num->wp - num->buf; 307 } 308 309 static int 310 tell(Num *num) 311 { 312 return num->rp - num->buf; 313 } 314 315 static void 316 seek(Num *num, int pos) 317 { 318 num->rp = num->buf + pos; 319 } 320 321 static void 322 rshift(Num *num, int n) 323 { 324 int diff; 325 326 diff = length(num) - n; 327 if (diff < 0) { 328 first(num); 329 numtrunc(num); 330 return; 331 } 332 333 memmove(num->buf, num->buf + n, diff); 334 num->rp = num->buf + diff; 335 numtrunc(num); 336 } 337 338 static void 339 lshift(Num *num, int n) 340 { 341 int len; 342 343 len = length(num); 344 expand(num, len + n); 345 memmove(num->buf + n, num->buf, len); 346 memset(num->buf, 0, n); 347 num->wp += n; 348 } 349 350 static Num * 351 chsign(Num *num) 352 { 353 int val, d, carry; 354 355 carry = 0; 356 for (first(num); more(num); next(num)) { 357 d = peek(num); 358 val = 100 - d - carry; 359 360 carry = 1; 361 if (val >= 100) { 362 val -= 100; 363 carry = 0; 364 } 365 poke(num, val); 366 } 367 368 prev(num); 369 if (carry != 0) { 370 if (peek(num) == 99) 371 poke(num, -1); 372 else 373 wrdigit(num, -1); 374 } else { 375 if (peek(num) == 0) 376 numtrunc(num); 377 } 378 379 return num; 380 } 381 382 static Num * 383 copy(Num *num) 384 { 385 Num *p; 386 int len = length(num); 387 388 p = new(len); 389 memcpy(p->buf, num->buf, len); 390 p->wp = p->buf + len; 391 p->rp = p->buf; 392 p->scale = num->scale; 393 394 return p; 395 } 396 397 static int 398 negative(Num *num) 399 { 400 return last(num) && peek(num) == -1; 401 } 402 403 static Num * 404 norm(Num *n) 405 { 406 /* trailing 0 */ 407 for (last(n); peek(n) == 0; numtrunc(n)) 408 ; 409 410 if (negative(n)) { 411 for (prev(n); peek(n) == 99; prev(n)) { 412 poke(n, -1); 413 next(n); 414 numtrunc(n); 415 } 416 } 417 418 /* adjust scale for 0 case*/ 419 if (length(n) == 0) 420 n->scale = 0; 421 return n; 422 } 423 424 static Num * 425 mulnto(Num *src, Num *dst, int n) 426 { 427 div_t dd; 428 int d, carry; 429 430 first(dst); 431 numtrunc(dst); 432 433 carry = 0; 434 for (first(src); more(src); next(src)) { 435 d = peek(src) * n + carry; 436 dd = div(d, 100); 437 carry = dd.quot; 438 wrdigit(dst, dd.rem); 439 } 440 441 if (carry) 442 wrdigit(dst, carry); 443 return dst; 444 } 445 446 static Num * 447 muln(Num *num, int n) 448 { 449 div_t dd; 450 int d, carry; 451 452 carry = 0; 453 for (first(num); more(num); next(num)) { 454 d = peek(num) * n + carry; 455 dd = div(d, 100); 456 carry = dd.quot; 457 poke(num, dd.rem); 458 } 459 460 if (carry) 461 wrdigit(num, carry); 462 return num; 463 } 464 465 static int 466 divn(Num *num, int n) 467 { 468 div_t dd; 469 int val, carry; 470 471 carry = 0; 472 for (last(num); !begin(num); prev(num)) { 473 val = carry * 100 + peek(num); 474 dd = div(val, n); 475 poke(num, dd.quot); 476 carry = dd.rem; 477 } 478 norm(num); 479 480 return carry; 481 } 482 483 static void 484 div10(Num *num, int n) 485 { 486 div_t dd = div(n, 2); 487 488 if (dd.rem == 1) 489 divn(num, 10); 490 491 rshift(num, dd.quot); 492 } 493 494 static void 495 mul10(Num *num, int n) 496 { 497 div_t dd = div(n, 2); 498 499 if (dd.rem == 1) 500 muln(num, 10); 501 502 lshift(num, dd.quot); 503 } 504 505 static void 506 align(Num *a, Num *b) 507 { 508 int d; 509 Num *max, *min; 510 511 d = a->scale - b->scale; 512 if (d == 0) { 513 return; 514 } else if (d > 0) { 515 min = b; 516 max = a; 517 } else { 518 min = a; 519 max = b; 520 } 521 522 d = abs(d); 523 mul10(min, d); 524 min->scale += d; 525 526 assert(min->scale == max->scale); 527 } 528 529 static Num * 530 addn(Num *num, int val) 531 { 532 int d, carry = val; 533 534 for (first(num); carry; next(num)) { 535 d = more(num) ? peek(num) : 0; 536 d += carry; 537 carry = 0; 538 539 if (d >= 100) { 540 carry = 1; 541 d -= 100; 542 } 543 poke(num, d); 544 } 545 546 return num; 547 } 548 549 static Num * 550 reverse(Num *num) 551 { 552 int d; 553 signed char *p, *q; 554 555 for (p = num->buf, q = num->wp - 1; p < q; ++p, --q) { 556 d = *p; 557 *p = *q; 558 *q = d; 559 } 560 561 return num; 562 } 563 564 static Num * 565 addnum(Num *a, Num *b) 566 { 567 Num *c; 568 int len, alen, blen, carry, da, db, sum; 569 570 align(a, b); 571 alen = length(a); 572 blen = length(b); 573 len = (alen > blen) ? alen : blen; 574 c = new(len); 575 576 first(a); 577 first(b); 578 carry = 0; 579 while (len-- > 0) { 580 da = (more(a)) ? rddigit(a) : 0; 581 db = (more(b)) ? rddigit(b) : 0; 582 583 sum = da + db + carry; 584 if (sum >= 100) { 585 carry = 1; 586 sum -= 100; 587 } else if (sum < 0) { 588 carry = -1; 589 sum += 100; 590 } else { 591 carry = 0; 592 } 593 594 wrdigit(c, sum); 595 } 596 597 if (carry) 598 wrdigit(c, carry); 599 c->scale = a->scale; 600 601 return norm(c); 602 } 603 604 static Num * 605 subnum(Num *a, Num *b) 606 { 607 Num *tmp, *sum; 608 609 tmp = chsign(copy(b)); 610 sum = addnum(a, tmp); 611 freenum(tmp); 612 613 return sum; 614 } 615 616 static Num * 617 mulnum(Num *a, Num *b) 618 { 619 Num shadow, *c, *ca, *cb; 620 int pos, prod, carry, dc, db, da, sc; 621 int asign = negative(a), bsign = negative(b); 622 623 c = zeronum(length(a) + length(b) + 1); 624 c->scale = a->scale + b->scale; 625 sc = (a->scale > b->scale) ? a->scale : b->scale; 626 627 ca = a; 628 if (asign) 629 ca = chsign(copy(ca)); 630 cb = b; 631 if (bsign) 632 cb = chsign(copy(cb)); 633 634 /* avoid aliasing problems when called from expnum*/ 635 if (ca == cb) { 636 shadow = *cb; 637 b = cb = &shadow; 638 } 639 640 for (first(cb); more(cb); next(cb)) { 641 div_t d; 642 643 carry = 0; 644 db = peek(cb); 645 646 pos = tell(c); 647 for (first(ca); more(ca); next(ca)) { 648 da = peek(ca); 649 dc = peek(c); 650 prod = da * db + dc + carry; 651 d = div(prod, 100); 652 carry = d.quot; 653 poke(c, d.rem); 654 next(c); 655 } 656 657 for ( ; carry > 0; carry = d.quot) { 658 dc = peek(c) + carry; 659 d = div(dc, 100); 660 poke(c, d.rem); 661 next(c); 662 } 663 seek(c, pos + 1); 664 } 665 norm(c); 666 667 if (sc < scale) 668 sc = scale; 669 sc = c->scale - sc; 670 if (sc > 0) { 671 div10(c, sc); 672 c->scale -= sc; 673 } 674 675 if (ca != a) 676 freenum(ca); 677 if (cb != b) 678 freenum(cb); 679 680 if (asign ^ bsign) 681 chsign(c); 682 return c; 683 } 684 685 /* 686 * The divmod function is implemented following the algorithm 687 * from the plan9 version that is not exactly like the one described 688 * in the paper. A lot of magic here. 689 */ 690 static Num * 691 divmod(Num *odivd, Num *odivr, Num **remp) 692 { 693 Num *acc, *divd, *divr, *res; 694 int divsign, remsign; 695 int under, magic, ndig, diff; 696 int d, q, carry, divcarry; 697 long dr, dd, cc; 698 699 divr = odivr; 700 acc = copy(&zero); 701 divd = copy(odivd); 702 res = zeronum(length(odivd)); 703 704 under = divcarry = divsign = remsign = 0; 705 706 if (length(divr) == 0) { 707 weprintf("divide by 0\n"); 708 goto ret; 709 } 710 711 divsign = negative(divd); 712 if (divsign) 713 chsign(divd); 714 715 remsign = negative(divr); 716 if (remsign) 717 divr = chsign(copy(divr)); 718 719 diff = length(divd) - length(divr); 720 721 seek(res, diff + 1); 722 last(divd); 723 last(divr); 724 725 wrdigit(divd, 0); 726 727 dr = peek(divr); 728 magic = dr < 10; 729 dr = dr * 100 + (prev(divr) ? peek(divr) : 0); 730 if (magic) { 731 dr = dr * 100 + (prev(divr) ? peek(divr) : 0); 732 dr *= 2; 733 dr /= 25; 734 } 735 736 for (ndig = 0; diff >= 0; ++ndig) { 737 last(divd); 738 dd = peek(divd); 739 dd = dd * 100 + (prev(divd) ? peek(divd) : 0); 740 dd = dd * 100 + (prev(divd) ? peek(divd) : 0); 741 cc = dr; 742 743 if (diff == 0) 744 dd++; 745 else 746 cc++; 747 748 if (magic) 749 dd *= 8; 750 751 q = dd / cc; 752 under = 0; 753 if (q > 0 && dd % cc < 8 && magic) { 754 q--; 755 under = 1; 756 } 757 758 mulnto(divr, acc, q); 759 760 /* Subtract acc from dividend at offset position */ 761 first(acc); 762 carry = 0; 763 for (seek(divd, diff); more(divd); next(divd)) { 764 d = peek(divd); 765 d = d - (more(acc) ? rddigit(acc) : 0) - carry; 766 carry = 0; 767 if (d < 0) { 768 d += 100; 769 carry = 1; 770 } 771 poke(divd, d); 772 } 773 divcarry = carry; 774 775 /* Store quotient digit */ 776 prev(res); 777 poke(res, q); 778 779 /* Handle borrow propagation */ 780 last(divd); 781 d = peek(divd); 782 if ((d != 0) && (diff != 0)) { 783 prev(divd); 784 d = peek(divd) + 100; 785 poke(divd, d); 786 } 787 788 /* Shorten dividend for next iteration */ 789 if (--diff >= 0) 790 divd->wp--; 791 } 792 793 /* 794 * if we have an underflow then we have to adjust 795 * the remaining and the result 796 */ 797 if (under) { 798 Num *p = subnum(divd, divr); 799 if (negative(p)) { 800 freenum(p); 801 } else { 802 freenum(divd); 803 poke(res, q + 1); 804 divd = p; 805 } 806 } 807 808 if (divcarry) { 809 Num *p; 810 811 poke(res, q - 1); 812 poke(divd, -1); 813 p = addnum(divr, divd); 814 freenum(divd); 815 divd = p; 816 } 817 818 divcarry = 0; 819 for (first(res); more(res); next(res)) { 820 d = peek(res) + divcarry; 821 divcarry = 0; 822 if (d >= 100) { 823 d -= 100; 824 divcarry = 1; 825 } 826 poke(res, d); 827 } 828 829 ret: 830 if (divsign) 831 chsign(divd); 832 if (divsign ^ remsign) 833 chsign(res); 834 835 if (remp) { 836 divd->scale = odivd->scale; 837 *remp = norm(divd); 838 } else { 839 freenum(divd); 840 } 841 842 if (divr != odivr) 843 freenum(divr); 844 845 freenum(acc); 846 847 res->scale = odivd->scale - odivr->scale; 848 if (res->scale < 0) 849 res->scale = 0; 850 851 return norm(res); 852 } 853 854 static int 855 divscale(Num *divd, Num *divr) 856 { 857 int diff; 858 859 if (length(divr) == 0) { 860 weprintf("divide by 0\n"); 861 return 0; 862 } 863 864 diff = scale + divr->scale - divd->scale; 865 866 if (diff > 0) { 867 mul10(divd, diff); 868 divd->scale += diff; 869 } else if (diff < 0) { 870 mul10(divr, -diff); 871 divr->scale += -diff; 872 } 873 874 return 1; 875 } 876 877 static Num * 878 divnum(Num *a, Num *b) 879 { 880 Num *r; 881 int siga, sigb; 882 883 siga = negative(a); 884 if (siga) 885 chsign(a); 886 887 sigb = negative(b); 888 if (sigb) 889 chsign(b); 890 891 if (!divscale(a, b)) 892 return copy(&zero); 893 894 r = divmod(a, b, NULL); 895 if (siga ^ sigb) 896 chsign(r); 897 return r; 898 } 899 900 static Num * 901 modnum(Num *a, Num *b) 902 { 903 Num *mod, *c; 904 int siga, sigb; 905 906 siga = negative(a); 907 if (siga) 908 chsign(a); 909 910 sigb = negative(b); 911 if (sigb) 912 chsign(b); 913 914 if (!divscale(a, b)) 915 return copy(&zero); 916 917 c = divmod(a, b, &mod); 918 freenum(c); 919 920 if (siga) 921 chsign(mod); 922 923 return mod; 924 } 925 926 static Num * 927 expnum(Num *base, Num *exp) 928 { 929 int neg, d; 930 Num *res, *fact, *e, *tmp1, *tmp2; 931 932 res = copy(&one); 933 if (length(exp) == 0) 934 return res; 935 936 e = copy(exp); 937 if ((neg = negative(exp)) != 0) 938 chsign(e); 939 940 if (e->scale > 0) { 941 div10(e, e->scale); 942 e->scale = 0; 943 } 944 945 fact = copy(base); 946 while (length(e) > 0) { 947 first(e); 948 d = peek(e); 949 if (d % 2 == 1) { 950 tmp1 = mulnum(res, fact); 951 freenum(res); 952 res = tmp1; 953 } 954 955 /* Square fact */ 956 tmp1 = mulnum(fact, fact); 957 freenum(fact); 958 fact = tmp1; 959 960 divn(e, 2); 961 } 962 freenum(fact); 963 freenum(e); 964 965 /* Handle negative exponent: 1 / res */ 966 if (neg) { 967 tmp2 = divnum(tmp1 = copy(&one), res); 968 freenum(tmp1); 969 freenum(res); 970 res = tmp2; 971 } 972 973 return res; 974 } 975 976 /* 977 * Compare two numbers: returns <0 if a<b, 0 if a==b, >0 if a>b 978 */ 979 static int 980 cmpnum(Num *a, Num *b) 981 { 982 Num *diff; 983 int result; 984 985 diff = subnum(a, b); 986 if (length(diff) == 0) 987 result = 0; 988 else if (negative(diff)) 989 result = -1; 990 else 991 result = 1; 992 freenum(diff); 993 994 return result; 995 } 996 997 /* 998 * Integer square root of a small integer (0-9999) 999 * Used for initial guess in Newton's method 1000 */ 1001 static int 1002 isqrt(int n) 1003 { 1004 int x, x1; 1005 1006 if (n <= 0) 1007 return 0; 1008 if (n == 1) 1009 return 1; 1010 1011 x = n; 1012 x1 = (x + 1) / 2; 1013 while (x1 < x) { 1014 x = x1; 1015 x1 = (x + n / x) / 2; 1016 } 1017 return x; 1018 } 1019 1020 /* 1021 * Square root using Newton's method: x_{n+1} = (x_n + y/x_n) / 2 1022 * 1023 * Key insight: sqrt(a * 10^(2n)) = sqrt(a) * 10^n 1024 * So we scale up the input to get the desired output precision. 1025 * 1026 * To compute sqrt with scale decimal places of precision: 1027 * 1. Scale up y by 10^(2*scale + 2) (extra 2 for guard digits) 1028 * 2. Compute integer sqrt 1029 * 3. Result has (scale + 1) decimal places, numtrunc to scale 1030 */ 1031 static Num * 1032 sqrtnum(Num *oy) 1033 { 1034 Num *y, *x, *xprev, *q, *sum; 1035 int top, ysc, iter; 1036 1037 if (length(oy) == 0) 1038 return copy(&zero); 1039 1040 if (negative(oy)) { 1041 weprintf("square root of negative number\n"); 1042 return copy(&zero); 1043 } 1044 1045 y = copy(oy); 1046 ysc = 2 * scale + 2 - y->scale; 1047 if (ysc > 0) 1048 mul10(y, ysc); 1049 ysc = 2 * scale + 2; 1050 1051 /* Make scale even (so sqrt gives integer result) */ 1052 if (ysc % 2 == 1) { 1053 muln(y, 10); 1054 ysc++; 1055 } 1056 y->scale = 0; 1057 1058 last(y); 1059 top = peek(y); 1060 if (prev(y) && length(y) > 1) 1061 top = top * 100 + peek(y); 1062 1063 x = new(0); 1064 wrdigit(x, isqrt(top)); 1065 x->scale = 0; 1066 1067 /* Scale up the initial guess to match the magnitude of y */ 1068 lshift(x, (length(y) - 1) / 2); 1069 1070 1071 /* Newton iteration: x = (x + y/x) / 2 */ 1072 xprev = NULL; 1073 for (iter = 0; iter < 1000; iter++) { 1074 q = divmod(y, x, NULL); 1075 sum = addnum(x, q); 1076 freenum(q); 1077 divn(sum, 2); 1078 1079 /* Check for convergence: sum == x or sum == prev */ 1080 if (cmpnum(sum, x) == 0) { 1081 freenum(sum); 1082 break; 1083 } 1084 if (xprev != NULL && cmpnum(sum, xprev) == 0) { 1085 /* Oscillating - pick smaller */ 1086 if (cmpnum(x, sum) < 0) { 1087 freenum(sum); 1088 } else { 1089 freenum(x); 1090 x = sum; 1091 } 1092 break; 1093 } 1094 1095 freenum(xprev); 1096 xprev = x; 1097 x = sum; 1098 } 1099 freenum(xprev); 1100 freenum(y); 1101 1102 /* Truncate to desired scale */ 1103 x->scale = ysc / 2; 1104 if (x->scale > scale) { 1105 int diff = x->scale - scale; 1106 div10(x, diff); 1107 x->scale = scale; 1108 } 1109 1110 return norm(x); 1111 } 1112 1113 static Num * 1114 tonum(void) 1115 { 1116 char *s, *t, *end, *dot; 1117 Num *num, *denom, *numer, *frac, *q, *rem; 1118 int sign, d, ch, nfrac; 1119 1120 s = input->s; 1121 num = new(0); 1122 sign = 0; 1123 if (*s == '_') { 1124 sign = 1; 1125 ++s; 1126 } 1127 1128 dot = NULL; 1129 for (t = s; (ch = *t) > 0 || ch <= UCHAR_MAX; ++t) { 1130 if (!strchr(digits, ch)) 1131 break; 1132 if (ch == '.') { 1133 if (dot) 1134 break; 1135 dot = t; 1136 } 1137 } 1138 input->s = end = t; 1139 1140 /* 1141 * Parse integer part: process digits left-to-right. 1142 * For each digit: num = num * ibase + digit 1143 */ 1144 for (t = s; t < (dot ? dot : end); ++t) { 1145 d = strchr(digits, *t) - digits; 1146 muln(num, ibase); 1147 addn(num, d); 1148 } 1149 norm(num); 1150 1151 if (!dot) 1152 goto ret; 1153 1154 /* 1155 * convert fractional digits 1156 * Algorithm: For digits d[0], d[1], ..., d[n-1] after '.' 1157 * Value = d[0]/ibase + d[1]/ibase^2 + ... + d[n-1]/ibase^n 1158 * 1159 * numerator = d[0]*ibase^(n-1) + d[1]*ibase^(n-2) + ... + d[n-1] 1160 * denominator = ibase^n 1161 * Then extract decimal digits by repeated: num*100/denom 1162 */ 1163 denom = copy(&one); 1164 numer = copy(&zero); 1165 for (t = dot + 1; t < end; ++t) { 1166 d = strchr(digits, *t) - digits; 1167 muln(denom, ibase); 1168 muln(numer, ibase); 1169 addn(numer, d); 1170 } 1171 1172 nfrac = end - dot - 1; 1173 frac = new(0); 1174 d = 0; 1175 while (frac->scale < nfrac || length(numer) > 0) { 1176 muln(numer, 100); 1177 q = divmod(numer, denom, &rem); 1178 freenum(numer); 1179 1180 d = first(q) ? peek(q) : 0; 1181 wrdigit(frac, d); 1182 freenum(q); 1183 numer = rem; 1184 frac->scale += 2; 1185 } 1186 reverse(frac); 1187 1188 /* Trim to exact input scale for odd nfrac */ 1189 if (frac->scale > nfrac && d % 10 == 0) { 1190 divn(frac, 10); 1191 frac->scale--; 1192 } 1193 1194 freenum(numer); 1195 freenum(denom); 1196 1197 q = addnum(num, frac); 1198 freenum(num); 1199 freenum(frac); 1200 num = q; 1201 1202 ret: 1203 if (sign) 1204 chsign(num); 1205 return num; 1206 } 1207 1208 static void 1209 prchr(int ch) 1210 { 1211 if (col >= 69) { 1212 putchar('\\'); 1213 putchar('\n'); 1214 col = 0; 1215 } 1216 putchar(ch); 1217 col++; 1218 } 1219 1220 static void 1221 printd(int d, int base, int space) 1222 { 1223 int w, n; 1224 1225 if (base <= 16) { 1226 prchr(digits[d]); 1227 } else { 1228 if (space) 1229 prchr(' '); 1230 1231 for (w = 1, n = base - 1; n >= 10; n /= 10) 1232 w++; 1233 1234 if (col + w > 69) { 1235 putchar('\\'); 1236 putchar('\n'); 1237 col = 0; 1238 } 1239 col += printf("%0*d", w, d); 1240 } 1241 } 1242 1243 static void 1244 pushdigit(struct digit **l, int val) 1245 { 1246 struct digit *it = emalloc(sizeof(*it)); 1247 1248 it->next = *l; 1249 it->val = val; 1250 *l = it; 1251 } 1252 1253 static int 1254 popdigit(struct digit **l) 1255 { 1256 int val; 1257 struct digit *next, *it = *l; 1258 1259 if (it == NULL) 1260 return -1; 1261 1262 val = it->val; 1263 next = it->next; 1264 free(it); 1265 *l = next; 1266 return val; 1267 } 1268 1269 static void 1270 printnum(Num *onum, int base) 1271 { 1272 struct digit *sp; 1273 int sc, i, sign, n; 1274 Num *num, *inte, *frac, *opow; 1275 1276 col = 0; 1277 if (length(onum) == 0) { 1278 prchr('0'); 1279 return; 1280 } 1281 1282 num = copy(onum); 1283 if ((sign = negative(num)) != 0) 1284 chsign(num); 1285 1286 sc = num->scale; 1287 if (num->scale % 2 == 1) { 1288 muln(num, 10); 1289 num->scale++; 1290 } 1291 inte = copy(num); 1292 rshift(inte, num->scale / 2); 1293 inte->scale = 0; 1294 frac = subnum(num, inte); 1295 1296 sp = NULL; 1297 for (i = 0; length(inte) > 0; ++i) 1298 pushdigit(&sp, divn(inte, base)); 1299 if (sign) 1300 prchr('-'); 1301 while (i-- > 0) 1302 printd(popdigit(&sp), base, 1); 1303 assert(sp == NULL); 1304 1305 if (num->scale == 0) 1306 goto ret; 1307 1308 /* 1309 * Print fractional part by repeated multiplication by base. 1310 * We maintain the fraction as: frac / 10^scale 1311 * 1312 * Algorithm: 1313 * 1. Multiply frac by base 1314 * 2. Output integer part (frac / 10^scale) 1315 * 3. Keep fractional part (frac % 10^scale) 1316 */ 1317 prchr('.'); 1318 1319 opow = copy(&one); 1320 mul10(opow, num->scale); 1321 1322 for (n = 0; n < sc; ++n) { 1323 int d; 1324 Num *q, *rem; 1325 1326 muln(frac, base); 1327 q = divmod(frac, opow, &rem); 1328 d = first(q) ? peek(q) : 0; 1329 freenum(frac); 1330 freenum(q); 1331 frac = rem; 1332 printd(d, base, n > 0); 1333 } 1334 freenum(opow); 1335 1336 ret: 1337 freenum(num); 1338 freenum(inte); 1339 freenum(frac); 1340 } 1341 1342 static int 1343 moreinput(void) 1344 { 1345 struct input *ip; 1346 1347 repeat: 1348 if (!input) 1349 return 0; 1350 1351 if (input->buf != NULL && *input->s != '\0') 1352 return 1; 1353 1354 if (input->fp) { 1355 if (getline(&input->buf, &input->n, input->fp) >= 0) { 1356 input->s = input->buf; 1357 return 1; 1358 } 1359 if (ferror(input->fp)) { 1360 eprintf("reading from file:"); 1361 exit(1); 1362 } 1363 fclose(input->fp); 1364 } 1365 1366 ip = input; 1367 input = ip->next; 1368 free(ip->buf); 1369 free(ip); 1370 goto repeat; 1371 } 1372 1373 static void 1374 addinput(FILE *fp, char *s) 1375 { 1376 struct input *ip; 1377 1378 assert((!fp && !s) == 0); 1379 1380 ip = emalloc(sizeof(*ip)); 1381 ip->next = input; 1382 ip->fp = fp; 1383 ip->n = 0; 1384 ip->s = ip->buf = s; 1385 input = ip; 1386 } 1387 1388 static void 1389 delinput(int cmd, int n) 1390 { 1391 if (n < 0) 1392 error("Q command requires a number >= 0"); 1393 while (n-- > 0) { 1394 if (cmd == 'Q' && !input->next) 1395 error("Q command argument exceeded string execution depth"); 1396 if (input->fp) 1397 fclose(input->fp); 1398 free(input->buf); 1399 input = input->next; 1400 if (!input) 1401 exit(0); 1402 } 1403 } 1404 1405 static void 1406 push(Val v) 1407 { 1408 Val *p = emalloc(sizeof(Val)); 1409 1410 *p = v; 1411 p->next = stack; 1412 stack = p; 1413 } 1414 1415 static void 1416 needstack(int n) 1417 { 1418 Val *vp; 1419 1420 for (vp = stack; n > 0 && vp; vp = vp->next) 1421 --n; 1422 if (n > 0) 1423 error("stack empty"); 1424 } 1425 1426 static Val 1427 pop(void) 1428 { 1429 Val v; 1430 1431 if (!stack) 1432 error("stack empty"); 1433 v = *stack; 1434 free(stack); 1435 stack = v.next; 1436 v.next = NULL; 1437 1438 return v; 1439 } 1440 1441 static Num * 1442 popnum(void) 1443 { 1444 Val v = pop(); 1445 1446 if (v.type != NUM) { 1447 free(v.u.s); 1448 error("non-numeric value"); 1449 } 1450 return v.u.n; 1451 } 1452 1453 static void 1454 pushnum(Num *num) 1455 { 1456 push((Val) {.type = NUM, .u.n = num}); 1457 } 1458 1459 static void 1460 pushstr(char *s) 1461 { 1462 push((Val) {.type = STR, .u.s = s}); 1463 } 1464 1465 static void 1466 arith(Num *(*fn)(Num *, Num *)) 1467 { 1468 Num *a, *b, *c; 1469 1470 needstack(2); 1471 b = popnum(); 1472 a = popnum(); 1473 c = (*fn)(a, b); 1474 freenum(a); 1475 freenum(b); 1476 pushnum(c); 1477 } 1478 1479 static void 1480 pushdivmod(void) 1481 { 1482 Num *a, *b, *q, *rem; 1483 1484 needstack(2); 1485 b = popnum(); 1486 a = popnum(); 1487 1488 if (!divscale(a, b)) { 1489 q = copy(&zero); 1490 rem = copy(&zero); 1491 } else { 1492 q = divmod(a, b, &rem); 1493 } 1494 1495 pushnum(q); 1496 pushnum(rem); 1497 freenum(a); 1498 freenum(b); 1499 } 1500 1501 static int 1502 popint(void) 1503 { 1504 Num *num; 1505 int r = -1, n, d; 1506 1507 num = popnum(); 1508 if (negative(num)) 1509 goto ret; 1510 1511 /* discard fraction part */ 1512 div10(num, num->scale); 1513 1514 n = 0; 1515 for (last(num); !begin(num); prev(num)) { 1516 if (n > INT_MAX / 100) 1517 goto ret; 1518 n *= 100; 1519 d = peek(num); 1520 if (n > INT_MAX - d) 1521 goto ret; 1522 n += d; 1523 } 1524 r = n; 1525 1526 ret: 1527 freenum(num); 1528 return r; 1529 } 1530 1531 static void 1532 pushint(int n) 1533 { 1534 div_t dd; 1535 Num *num; 1536 1537 num = new(0); 1538 for ( ; n > 0; n = dd.quot) { 1539 dd = div(n, 100); 1540 wrdigit(num, dd.rem); 1541 } 1542 pushnum(num); 1543 } 1544 1545 static void 1546 printval(Val v) 1547 { 1548 if (v.type == STR) 1549 fputs(v.u.s, stdout); 1550 else 1551 printnum(v.u.n, obase); 1552 } 1553 1554 static Val 1555 dupval(Val v) 1556 { 1557 Val nv; 1558 1559 switch (nv.type = v.type) { 1560 case STR: 1561 nv.u.s = estrdup(v.u.s); 1562 break; 1563 case NUM: 1564 nv.u.n = copy(v.u.n); 1565 break; 1566 case NVAL: 1567 nv.type = NUM; 1568 nv.u.n = copy(&zero); 1569 break; 1570 } 1571 nv.next = NULL; 1572 1573 return nv; 1574 } 1575 1576 static void 1577 freeval(Val v) 1578 { 1579 if (v.type == STR) 1580 free(v.u.s); 1581 else if (v.type == NUM) 1582 freenum(v.u.n); 1583 } 1584 1585 static void 1586 dumpstack(void) 1587 { 1588 Val *vp; 1589 1590 for (vp = stack; vp; vp = vp->next) { 1591 printval(*vp); 1592 putchar('\n'); 1593 } 1594 } 1595 1596 static void 1597 clearstack(void) 1598 { 1599 Val *vp, *next; 1600 1601 for (vp = stack; vp; vp = next) { 1602 next = vp->next; 1603 freeval(*vp); 1604 free(vp); 1605 } 1606 stack = NULL; 1607 } 1608 1609 static void 1610 dupstack(void) 1611 { 1612 Val v; 1613 1614 push(v = pop()); 1615 push(dupval(v)); 1616 } 1617 1618 static void 1619 deepstack(void) 1620 { 1621 int n; 1622 Val *vp; 1623 1624 n = 0; 1625 for (vp = stack; vp; vp = vp->next) { 1626 if (n == INT_MAX) 1627 error("stack depth does not fit in a integer"); 1628 ++n; 1629 } 1630 pushint(n); 1631 } 1632 1633 static void 1634 pushfrac(void) 1635 { 1636 Val v = pop(); 1637 1638 if (v.type == STR) 1639 pushint(0); 1640 else 1641 pushint(v.u.n->scale); 1642 freeval(v); 1643 } 1644 1645 static void 1646 pushlen(void) 1647 { 1648 int n; 1649 Num *num; 1650 Val v = pop(); 1651 1652 if (v.type == STR) { 1653 n = strlen(v.u.s); 1654 } else { 1655 num = v.u.n; 1656 if (length(num) == 0) { 1657 n = 1; 1658 } else { 1659 n = length(num) * 2; 1660 n -= last(num) ? peek(num) < 10 : 0; 1661 } 1662 } 1663 pushint(n); 1664 freeval(v); 1665 } 1666 1667 static void 1668 setibase(void) 1669 { 1670 int n = popint(); 1671 1672 if (n < 2 || n > 16) 1673 error("input base must be an integer between 2 and 16"); 1674 ibase = n; 1675 } 1676 1677 static void 1678 setobase(void) 1679 { 1680 int n = popint(); 1681 1682 if (n < 2) 1683 error("output base must be an integer greater than 1"); 1684 obase = n; 1685 } 1686 1687 static char * 1688 string(char *dst, int *np) 1689 { 1690 int n, ch; 1691 1692 n = np ? *np : 0; 1693 for (;;) { 1694 ch = *input->s++; 1695 1696 switch (ch) { 1697 case '\0': 1698 if (!moreinput()) 1699 exit(0); 1700 break; 1701 case '\\': 1702 if (*input->s == '[') { 1703 dst = erealloc(dst, n + 1); 1704 dst[n++] = *input->s++; 1705 break; 1706 } 1707 goto copy; 1708 case ']': 1709 if (!np) { 1710 dst = erealloc(dst, n + 1); 1711 dst[n] = '\0'; 1712 return dst; 1713 } 1714 case '[': 1715 default: 1716 copy: 1717 dst = erealloc(dst, n + 1); 1718 dst[n++] = ch; 1719 if (ch == '[') 1720 dst = string(dst, &n); 1721 if (ch == ']') { 1722 *np = n; 1723 return dst; 1724 } 1725 } 1726 } 1727 } 1728 1729 static void 1730 setscale(void) 1731 { 1732 int n = popint(); 1733 1734 if (n < 0) 1735 error("scale must be a nonnegative integer"); 1736 scale = n; 1737 } 1738 1739 static unsigned 1740 hash(char *name) 1741 { 1742 int c; 1743 unsigned h = 5381; 1744 1745 while (c = *name++) 1746 h = h*33 ^ c; 1747 1748 return h; 1749 } 1750 1751 static struct reg * 1752 lookup(char *name) 1753 { 1754 struct reg *rp; 1755 int h = hash(name) & HASHSIZ-1; 1756 1757 for (rp = htbl[h]; rp; rp = rp->next) { 1758 if (strcmp(name, rp->name) == 0) 1759 return rp; 1760 } 1761 1762 rp = emalloc(sizeof(*rp)); 1763 rp->next = htbl[h]; 1764 htbl[h] = rp; 1765 rp->name = estrdup(name); 1766 1767 rp->val.type = NVAL; 1768 rp->val.next = NULL; 1769 1770 rp->ary.n = 0; 1771 rp->ary.buf = NULL; 1772 rp->ary.next = NULL; 1773 1774 return rp; 1775 } 1776 1777 static char * 1778 regname(void) 1779 { 1780 int delim, ch; 1781 char *s; 1782 static char name[REGSIZ]; 1783 1784 ch = *input->s++; 1785 if (!iflag || ch != '<' && ch != '"') { 1786 name[0] = ch; 1787 name[1] = '\0'; 1788 return name; 1789 } 1790 1791 if ((delim = ch) == '<') 1792 delim = '>'; 1793 1794 for (s = name; s < &name[REGSIZ]; ++s) { 1795 ch = *input->s++; 1796 if (ch == '\0' || ch == delim) { 1797 *s = '\0'; 1798 if (ch == '>') { 1799 name[0] = atoi(name); 1800 name[1] = '\0'; 1801 } 1802 return name; 1803 } 1804 *s = ch; 1805 } 1806 1807 error("identifier too long"); 1808 } 1809 1810 static void 1811 popreg(void) 1812 { 1813 int i; 1814 Val *vnext; 1815 struct ary *anext; 1816 char *s = regname(); 1817 struct reg *rp = lookup(s); 1818 1819 if (rp->val.type == NVAL) 1820 error("stack register '%s' (%o) is empty", s, s[0]); 1821 1822 push(rp->val); 1823 vnext = rp->val.next; 1824 if (!vnext) { 1825 rp->val.type = NVAL; 1826 } else { 1827 rp->val = *vnext; 1828 free(vnext); 1829 } 1830 1831 for (i = 0; i < rp->ary.n; ++i) 1832 freeval(rp->ary.buf[i]); 1833 free(rp->ary.buf); 1834 1835 anext = rp->ary.next; 1836 if (!anext) { 1837 rp->ary.n = 0; 1838 rp->ary.buf = NULL; 1839 } else { 1840 rp->ary = *anext; 1841 free(anext); 1842 } 1843 } 1844 1845 static void 1846 pushreg(void) 1847 { 1848 Val v; 1849 Val *vp; 1850 struct ary *ap; 1851 struct reg *rp = lookup(regname()); 1852 1853 v = pop(); 1854 1855 vp = emalloc(sizeof(Val)); 1856 *vp = rp->val; 1857 rp->val = v; 1858 rp->val.next = vp; 1859 1860 ap = emalloc(sizeof(struct ary)); 1861 *ap = rp->ary; 1862 rp->ary.n = 0; 1863 rp->ary.buf = NULL; 1864 rp->ary.next = ap; 1865 } 1866 1867 static Val * 1868 aryidx(void) 1869 { 1870 int n; 1871 int i; 1872 Val *vp; 1873 struct reg *rp = lookup(regname()); 1874 struct ary *ap = &rp->ary; 1875 1876 n = popint(); 1877 if (n < 0) 1878 error("array index must fit in a positive integer"); 1879 1880 if (n >= ap->n) { 1881 ap->buf = ereallocarray(ap->buf, n+1, sizeof(Val)); 1882 for (i = ap->n; i <= n; ++i) 1883 ap->buf[i].type = NVAL; 1884 ap->n = n + 1; 1885 } 1886 return &ap->buf[n]; 1887 } 1888 1889 static void 1890 aryget(void) 1891 { 1892 Val *vp = aryidx(); 1893 1894 push(dupval(*vp)); 1895 } 1896 1897 static void 1898 aryset(void) 1899 { 1900 Val val, *vp = aryidx(); 1901 1902 val = pop(); 1903 freeval(*vp); 1904 *vp = val; 1905 } 1906 1907 static void 1908 execmacro(void) 1909 { 1910 int ch; 1911 Val v = pop(); 1912 1913 assert(v.type != NVAL); 1914 if (v.type == NUM) { 1915 push(v); 1916 return; 1917 } 1918 1919 if (input->fp) { 1920 addinput(NULL, v.u.s); 1921 return; 1922 } 1923 1924 for (ch = *input->s; ch > 0 && ch <= UCHAR_MAX; ch = *input->s) { 1925 if (!isspace(ch)) 1926 break; 1927 ++input->s; 1928 } 1929 1930 /* check for tail recursion */ 1931 if (ch == '\0' && strcmp(input->buf, v.u.s) == 0) { 1932 free(input->buf); 1933 input->buf = input->s = v.u.s; 1934 return; 1935 } 1936 1937 addinput(NULL, v.u.s); 1938 } 1939 1940 static void 1941 relational(int ch) 1942 { 1943 int r; 1944 char *s; 1945 Num *a, *b; 1946 struct reg *rp = lookup(regname()); 1947 1948 needstack(2); 1949 a = popnum(); 1950 b = popnum(); 1951 r = cmpnum(a, b); 1952 freenum(a); 1953 freenum(b); 1954 1955 switch (ch) { 1956 case '>': 1957 r = r > 0; 1958 break; 1959 case '<': 1960 r = r < 0; 1961 break; 1962 case '=': 1963 r = r == 0; 1964 break; 1965 case LE: 1966 r = r <= 0; 1967 break; 1968 case GE: 1969 r = r >= 0; 1970 break; 1971 case NE: 1972 r = r != 0; 1973 break; 1974 default: 1975 abort(); 1976 } 1977 1978 if (!r) 1979 return; 1980 1981 push(dupval(rp->val)); 1982 execmacro(); 1983 } 1984 1985 static void 1986 printbytes(void) 1987 { 1988 Num *num; 1989 Val v = pop(); 1990 1991 if (v.type == STR) { 1992 fputs(v.u.s, stdout); 1993 } else { 1994 num = v.u.n; 1995 div10(num, num->scale); 1996 num->scale = 0; 1997 printnum(num, 100); 1998 } 1999 freeval(v); 2000 } 2001 2002 static void 2003 eval(void) 2004 { 2005 int ch; 2006 char *s; 2007 Num *num; 2008 size_t siz; 2009 Val v1, v2; 2010 struct reg *rp; 2011 2012 if (setjmp(env)) 2013 return; 2014 2015 for (s = input->s; (ch = *s) != '\0'; ++s) { 2016 if (ch < 0 || ch > UCHAR_MAX || !isspace(ch)) 2017 break; 2018 } 2019 input->s = s + (ch != '\0'); 2020 2021 switch (ch) { 2022 case '\0': 2023 break; 2024 case 'n': 2025 v1 = pop(); 2026 printval(v1); 2027 freeval(v1); 2028 break; 2029 case 'p': 2030 v1 = pop(); 2031 printval(v1); 2032 putchar('\n'); 2033 push(v1); 2034 break; 2035 case 'P': 2036 printbytes(); 2037 break; 2038 case 'f': 2039 dumpstack(); 2040 break; 2041 case '+': 2042 arith(addnum); 2043 break; 2044 case '-': 2045 arith(subnum); 2046 break; 2047 case '*': 2048 arith(mulnum); 2049 break; 2050 case '/': 2051 arith(divnum); 2052 break; 2053 case '%': 2054 arith(modnum); 2055 break; 2056 case '^': 2057 arith(expnum); 2058 break; 2059 case '~': 2060 pushdivmod(); 2061 break; 2062 case 'v': 2063 num = popnum(); 2064 pushnum(sqrtnum(num)); 2065 freenum(num); 2066 break; 2067 case 'c': 2068 clearstack(); 2069 break; 2070 case 'd': 2071 dupstack(); 2072 break; 2073 case 'r': 2074 needstack(2); 2075 v1 = pop(); 2076 v2 = pop(); 2077 push(v1); 2078 push(v2); 2079 break; 2080 case 'S': 2081 pushreg(); 2082 break; 2083 case 'L': 2084 popreg(); 2085 break; 2086 case 's': 2087 rp = lookup(regname()); 2088 v1 = pop(); 2089 freeval(rp->val); 2090 rp->val.u = v1.u; 2091 rp->val.type = v1.type; 2092 break; 2093 case 'l': 2094 rp = lookup(regname()); 2095 push(dupval(rp->val)); 2096 break; 2097 case 'i': 2098 setibase(); 2099 break; 2100 case 'o': 2101 setobase(); 2102 break; 2103 case 'k': 2104 setscale(); 2105 break; 2106 case 'I': 2107 pushint(ibase); 2108 break; 2109 case 'O': 2110 pushint(obase); 2111 break; 2112 case 'K': 2113 pushint(scale); 2114 break; 2115 case '[': 2116 pushstr(string(NULL, NULL)); 2117 break; 2118 case 'x': 2119 execmacro(); 2120 break; 2121 case '!': 2122 switch (*input->s++) { 2123 case '<': 2124 ch = GE; 2125 break; 2126 case '>': 2127 ch = LE; 2128 break; 2129 case '=': 2130 ch = NE; 2131 break; 2132 default: 2133 system(input->s-1); 2134 goto discard; 2135 } 2136 case '>': 2137 case '<': 2138 case '=': 2139 relational(ch); 2140 break; 2141 case '?': 2142 s = NULL; 2143 if (getline(&s, &siz, stdin) > 0) { 2144 pushstr(s); 2145 } else { 2146 free(s); 2147 if (ferror(stdin)) 2148 eprintf("reading from file\n"); 2149 } 2150 break; 2151 case 'q': 2152 delinput('q', 2); 2153 break; 2154 case 'Q': 2155 delinput('Q', popint()); 2156 break; 2157 case 'Z': 2158 pushlen(); 2159 break; 2160 case 'X': 2161 pushfrac(); 2162 break; 2163 case 'z': 2164 deepstack(); 2165 break; 2166 case '#': 2167 discard: 2168 while (*input->s) 2169 ++input->s; 2170 break; 2171 case ':': 2172 aryset(); 2173 break; 2174 case ';': 2175 aryget(); 2176 break; 2177 default: 2178 if (!strchr(digits, ch)) 2179 error("'%c' (%#o) unimplemented", ch, ch); 2180 case '_': 2181 --input->s; 2182 pushnum(tonum()); 2183 break; 2184 } 2185 } 2186 2187 static void 2188 dc(char *fname) 2189 { 2190 FILE *fp; 2191 2192 if (strcmp(fname, "-") == 0) { 2193 fp = stdin; 2194 } else { 2195 if ((fp = fopen(fname, "r")) == NULL) 2196 eprintf("opening '%s':", fname); 2197 } 2198 addinput(fp, NULL); 2199 2200 while (moreinput()) 2201 eval(); 2202 2203 free(input); 2204 input = NULL; 2205 } 2206 2207 static void 2208 usage(void) 2209 { 2210 eprintf("usage: dc [-i] [file ...]\n"); 2211 } 2212 2213 int 2214 main(int argc, char *argv[]) 2215 { 2216 ARGBEGIN { 2217 case 'i': 2218 iflag = 1; 2219 break; 2220 default: 2221 usage(); 2222 } ARGEND 2223 2224 while (*argv) 2225 dc(*argv++); 2226 dc("-"); 2227 2228 return 0; 2229 }