dc.c - sbase - suckless unix tools
HTML git clone git://git.suckless.org/sbase
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
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 }