sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

dc.c (31011B)


      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 	/* Adjust scale to max(a->scale, b->scale) while c is still positive */
    668 	sc = c->scale - sc;
    669 	if (sc > 0) {
    670 		div10(c, sc);
    671 		c->scale -= sc;
    672 	}
    673 
    674 	if (ca != a)
    675 		freenum(ca);
    676 	if (cb != b)
    677 		freenum(cb);
    678 
    679 	if (asign ^ bsign)
    680 		chsign(c);
    681 	return c;
    682 }
    683 
    684 /*
    685  * The divmod function is implemented following the algorithm
    686  * from the plan9 version that is not exactly like the one described
    687  * in the paper. A lot of magic here.
    688  */
    689 static Num *
    690 divmod(Num *odivd, Num *odivr, Num **remp)
    691 {
    692 	Num *acc, *divd, *divr, *res;
    693 	int divsign, remsign;
    694 	int under, magic, ndig, diff;
    695 	int d, q, carry, divcarry;
    696 	long dr, dd, cc;
    697 
    698 	divr = odivr;
    699 	acc = copy(&zero);
    700 	divd = copy(odivd);
    701 	res = zeronum(length(odivd));
    702 
    703 	under = divcarry = divsign = remsign = 0;
    704 
    705 	if (length(divr) == 0) {
    706 		weprintf("divide by 0\n");
    707 		goto ret;
    708 	}
    709 
    710 	divsign = negative(divd);
    711 	if (divsign)
    712 		chsign(divd);
    713 
    714 	remsign = negative(divr);
    715 	if (remsign)
    716 		divr = chsign(copy(divr));
    717 
    718 	diff = length(divd) - length(divr);
    719 
    720 	seek(res, diff + 1);
    721 	last(divd);
    722 	last(divr);
    723 
    724 	wrdigit(divd, 0);
    725 
    726 	dr = peek(divr);
    727 	magic = dr < 10;
    728 	dr = dr * 100 + (prev(divr) ? peek(divr) : 0);
    729 	if (magic) {
    730 		dr = dr * 100 + (prev(divr) ? peek(divr) : 0);
    731 		dr *= 2;
    732 		dr /= 25;
    733 	}
    734 
    735 	for (ndig = 0; diff >= 0; ++ndig) {
    736 		last(divd);
    737 		dd = peek(divd);
    738 		dd = dd * 100 + (prev(divd) ? peek(divd) : 0);
    739 		dd = dd * 100 + (prev(divd) ? peek(divd) : 0);
    740 		cc = dr;
    741 
    742 		if (diff == 0)
    743 			dd++;
    744 		else
    745 			cc++;
    746 
    747 		if (magic)
    748 			dd *= 8;
    749 
    750 		q = dd / cc;
    751 		under = 0;
    752 		if (q > 0 && dd % cc < 8 && magic) {
    753 			q--;
    754 			under = 1;
    755 		}
    756 
    757 		mulnto(divr, acc, q);
    758 
    759 		/* Subtract acc from dividend at offset position */
    760 		first(acc);
    761 		carry = 0;
    762 		for (seek(divd, diff); more(divd); next(divd)) {
    763 			d = peek(divd);
    764 			d = d - (more(acc) ? rddigit(acc) : 0) - carry;
    765 			carry = 0;
    766 			if (d < 0) {
    767 				d += 100;
    768 				carry = 1;
    769 			}
    770 			poke(divd, d);
    771 		}
    772 		divcarry = carry;
    773 
    774 		/* Store quotient digit */
    775 		prev(res);
    776 		poke(res, q);
    777 
    778 		/* Handle borrow propagation */
    779 		last(divd);
    780 		d = peek(divd);
    781 		if ((d != 0) && (diff != 0)) {
    782 			prev(divd);
    783 			d = peek(divd) + 100;
    784 			poke(divd, d);
    785 		}
    786 
    787 		/* Shorten dividend for next iteration */
    788 		if (--diff >= 0)
    789 			divd->wp--;
    790 	}
    791 
    792 	/*
    793 	 * if we have an underflow then we have to adjust
    794 	 * the remaining and the result
    795 	 */
    796 	if (under) {
    797 		Num *p = subnum(divd, divr);
    798 		if (negative(p)) {
    799 			freenum(p);
    800 		} else {
    801 			freenum(divd);
    802 			poke(res, q + 1);
    803 			divd = p;
    804 		}
    805 	}
    806 
    807 	if (divcarry) {
    808 		Num *p;
    809 
    810 		poke(res, q - 1);
    811 		poke(divd, -1);
    812 		p = addnum(divr, divd);
    813 		freenum(divd);
    814 		divd = p;
    815 	}
    816 
    817 	divcarry = 0;
    818 	for (first(res); more(res); next(res)) {
    819 		d = peek(res) + divcarry;
    820 		divcarry = 0;
    821 		if (d >= 100) {
    822 			d -= 100;
    823 			divcarry = 1;
    824 		}
    825 		poke(res, d);
    826 	}
    827 
    828 ret:
    829 	if (divsign)
    830 		chsign(divd);
    831 	if (divsign ^ remsign)
    832 		chsign(res);
    833 
    834 	if (remp) {
    835 		divd->scale = odivd->scale;
    836 		*remp = norm(divd);
    837 	} else {
    838 		freenum(divd);
    839 	}
    840 
    841 	if (divr != odivr)
    842 		freenum(divr);
    843 
    844 	freenum(acc);
    845 
    846 	res->scale = odivd->scale - odivr->scale;
    847 	if (res->scale < 0)
    848 		res->scale = 0;
    849 
    850 	return norm(res);
    851 }
    852 
    853 static int
    854 divscale(Num *divd, Num *divr)
    855 {
    856 	int diff;
    857 
    858 	if (length(divr) == 0) {
    859 		weprintf("divide by 0\n");
    860 		return 0;
    861 	}
    862 
    863 	diff = scale + divr->scale - divd->scale;
    864 
    865 	if (diff > 0) {
    866 		mul10(divd, diff);
    867 		divd->scale += diff;
    868 	} else if (diff < 0) {
    869 		mul10(divr, -diff);
    870 		divr->scale += -diff;
    871 	}
    872 
    873 	return 1;
    874 }
    875 
    876 static Num *
    877 divnum(Num *a, Num *b)
    878 {
    879 	if (!divscale(a, b))
    880 		return copy(&zero);
    881 
    882 	return divmod(a, b, NULL);
    883 }
    884 
    885 static Num *
    886 modnum(Num *a, Num *b)
    887 {
    888 	Num *mod, *c;
    889 
    890 	if (!divscale(a, b))
    891 		return copy(&zero);
    892 
    893 	c = divmod(a, b, &mod);
    894 	freenum(c);
    895 
    896 	return mod;
    897 }
    898 
    899 static Num *
    900 expnum(Num *base, Num *exp)
    901 {
    902 	int neg, d;
    903 	Num *res, *fact, *e, *tmp1, *tmp2;
    904 
    905 	res = copy(&one);
    906 	if (length(exp) == 0)
    907 		return res;
    908 
    909 	e = copy(exp);
    910 	if ((neg = negative(exp)) != 0)
    911 		chsign(e);
    912 
    913 	if (e->scale > 0) {
    914 		div10(e, e->scale);
    915 		e->scale = 0;
    916 	}
    917 
    918 	fact = copy(base);
    919 	while (length(e) > 0) {
    920 		first(e);
    921 		d = peek(e);
    922 		if (d % 2 == 1) {
    923 			tmp1 = mulnum(res, fact);
    924 			freenum(res);
    925 			res = tmp1;
    926 		}
    927 
    928 		/* Square fact */
    929 		tmp1 = mulnum(fact, fact);
    930 		freenum(fact);
    931 		fact = tmp1;
    932 
    933 		divn(e, 2);
    934 	}
    935 	freenum(fact);
    936 	freenum(e);
    937 
    938 	/* Handle negative exponent: 1 / res */
    939 	if (neg) {
    940 		tmp2 = divnum(tmp1 = copy(&one), res);
    941 		freenum(tmp1);
    942 		freenum(res);
    943 		res = tmp2;
    944 	}
    945 
    946 	return res;
    947 }
    948 
    949 /*
    950  * Compare two numbers: returns <0 if a<b, 0 if a==b, >0 if a>b
    951  */
    952 static int
    953 cmpnum(Num *a, Num *b)
    954 {
    955 	Num *diff;
    956 	int result;
    957 
    958 	diff = subnum(a, b);
    959 	if (length(diff) == 0)
    960 		result = 0;
    961 	else if (negative(diff))
    962 		result = -1;
    963 	else
    964 		result = 1;
    965 	freenum(diff);
    966 
    967 	return result;
    968 }
    969 
    970 /*
    971  * Integer square root of a small integer (0-9999)
    972  * Used for initial guess in Newton's method
    973  */
    974 static int
    975 isqrt(int n)
    976 {
    977 	int x, x1;
    978 
    979 	if (n <= 0)
    980 		return 0;
    981 	if (n == 1)
    982 		return 1;
    983 
    984 	x = n;
    985 	x1 = (x + 1) / 2;
    986 	while (x1 < x) {
    987 		x = x1;
    988 		x1 = (x + n / x) / 2;
    989 	}
    990 	return x;
    991 }
    992 
    993 /*
    994  * Square root using Newton's method: x_{n+1} = (x_n + y/x_n) / 2
    995  *
    996  * Key insight: sqrt(a * 10^(2n)) = sqrt(a) * 10^n
    997  * So we scale up the input to get the desired output precision.
    998  *
    999  * To compute sqrt with scale decimal places of precision:
   1000  * 1. Scale up y by 10^(2*scale + 2) (extra 2 for guard digits)
   1001  * 2. Compute integer sqrt
   1002  * 3. Result has (scale + 1) decimal places, numtrunc to scale
   1003  */
   1004 static Num *
   1005 sqrtnum(Num *oy)
   1006 {
   1007 	Num *y, *x, *xprev, *q, *sum;
   1008 	int top, ysc, iter;
   1009 
   1010 	if (length(oy) == 0)
   1011 		return copy(&zero);
   1012 
   1013 	if (negative(oy)) {
   1014 		weprintf("square root of negative number\n");
   1015 		return copy(&zero);
   1016 	}
   1017 
   1018 	y = copy(oy);
   1019 	ysc = 2 * scale + 2 - y->scale;
   1020 	if (ysc > 0)
   1021 		mul10(y, ysc);
   1022 	ysc = 2 * scale + 2;
   1023 
   1024 	/* Make scale even (so sqrt gives integer result) */
   1025 	if (ysc % 2 == 1) {
   1026 		muln(y, 10);
   1027 		ysc++;
   1028 	}
   1029 	y->scale = 0;
   1030 
   1031 	last(y);
   1032 	top = peek(y);
   1033 	if (prev(y) && length(y) > 1)
   1034 		top = top * 100 + peek(y);
   1035 
   1036 	x = new(0);
   1037 	wrdigit(x, isqrt(top));
   1038 	x->scale = 0;
   1039 
   1040 	/* Scale up the initial guess to match the magnitude of y */
   1041 	lshift(x, (length(y) - 1) / 2);
   1042 
   1043 
   1044 	/* Newton iteration: x = (x + y/x) / 2 */
   1045 	xprev = NULL;
   1046 	for (iter = 0; iter < 1000; iter++) {
   1047 		q = divmod(y, x, NULL);
   1048 		sum = addnum(x, q);
   1049 		freenum(q);
   1050 		divn(sum, 2);
   1051 
   1052 		/* Check for convergence: sum == x or sum == prev */
   1053 		if (cmpnum(sum, x) == 0) {
   1054 			freenum(sum);
   1055 			break;
   1056 		}
   1057 		if (xprev != NULL && cmpnum(sum, xprev) == 0) {
   1058 			/* Oscillating - pick smaller */
   1059 			if (cmpnum(x, sum) < 0) {
   1060 				freenum(sum);
   1061 			} else {
   1062 				freenum(x);
   1063 				x = sum;
   1064 			}
   1065 			break;
   1066 		}
   1067 
   1068 		freenum(xprev);
   1069 		xprev = x;
   1070 		x = sum;
   1071 	}
   1072 	freenum(xprev);
   1073 	freenum(y);
   1074 
   1075 	/* Truncate to desired scale */
   1076 	x->scale = ysc / 2;
   1077 	if (x->scale > scale) {
   1078 		int diff = x->scale - scale;
   1079 		div10(x, diff);
   1080 		x->scale = scale;
   1081 	}
   1082 
   1083 	return norm(x);
   1084 }
   1085 
   1086 static Num *
   1087 tonum(void)
   1088 {
   1089 	char *s, *t, *end, *dot;
   1090 	Num *num, *denom, *numer, *frac, *q, *rem;
   1091 	int sign, d, ch, nfrac;
   1092 
   1093 	s = input->s;
   1094 	num = new(0);
   1095 	sign = 0;
   1096 	if (*s == '_') {
   1097 		sign = 1;
   1098 		++s;
   1099 	}
   1100 
   1101 	dot = NULL;
   1102 	for (t = s; (ch = *t) > 0 || ch <= UCHAR_MAX; ++t) {
   1103 		if (!strchr(digits, ch))
   1104 			break;
   1105 		if (ch == '.') {
   1106 			if (dot)
   1107 				break;
   1108 			dot = t;
   1109 		}
   1110 	}
   1111 	input->s = end = t;
   1112 
   1113 	/*
   1114 	 * Parse integer part: process digits left-to-right.
   1115 	 * For each digit: num = num * ibase + digit
   1116 	 */
   1117 	for (t = s; t < (dot ? dot : end); ++t) {
   1118 		d = strchr(digits, *t) - digits;
   1119 		muln(num, ibase);
   1120 		addn(num, d);
   1121 	}
   1122 	norm(num);
   1123 
   1124 	if (!dot)
   1125 		goto ret;
   1126 
   1127 	/*
   1128 	 * convert fractional digits
   1129 	 * Algorithm: For digits d[0], d[1], ..., d[n-1] after '.'
   1130 	 * Value = d[0]/ibase + d[1]/ibase^2 + ... + d[n-1]/ibase^n
   1131 	 *
   1132 	 * numerator = d[0]*ibase^(n-1) + d[1]*ibase^(n-2) + ... + d[n-1]
   1133 	 * denominator = ibase^n
   1134 	 * Then extract decimal digits by repeated: num*100/denom
   1135 	 */
   1136 	denom = copy(&one);
   1137 	numer = copy(&zero);
   1138 	for (t = dot + 1; t < end; ++t) {
   1139 		d = strchr(digits, *t) - digits;
   1140 		muln(denom, ibase);
   1141 		muln(numer, ibase);
   1142 		addn(numer, d);
   1143 	}
   1144 
   1145 	nfrac = end - dot - 1;
   1146 	frac = new(0);
   1147 	d = 0;
   1148 	while (frac->scale < nfrac || length(numer) > 0) {
   1149 		muln(numer, 100);
   1150 		q = divmod(numer, denom, &rem);
   1151 		freenum(numer);
   1152 
   1153 		d = first(q) ? peek(q) : 0;
   1154 		wrdigit(frac, d);
   1155 		freenum(q);
   1156 		numer = rem;
   1157 		frac->scale += 2;
   1158 	}
   1159 	reverse(frac);
   1160 
   1161 	/* Trim to exact input scale for odd nfrac */
   1162 	if (frac->scale > nfrac && d % 10 == 0) {
   1163 		divn(frac, 10);
   1164 		frac->scale--;
   1165 	}
   1166 
   1167 	freenum(numer);
   1168 	freenum(denom);
   1169 
   1170 	q = addnum(num, frac);
   1171 	freenum(num);
   1172 	freenum(frac);
   1173 	num = q;
   1174 
   1175 ret:
   1176 	if (sign)
   1177 		chsign(num);
   1178 	return num;
   1179 }
   1180 
   1181 static void
   1182 prchr(int ch)
   1183 {
   1184 	if (col >= 69) {
   1185 		putchar('\\');
   1186 		putchar('\n');
   1187 		col = 0;
   1188 	}
   1189 	putchar(ch);
   1190 	col++;
   1191 }
   1192 
   1193 static void
   1194 printd(int d, int base, int space)
   1195 {
   1196 	int w, n;
   1197 
   1198 	if (base <= 16) {
   1199 		prchr(digits[d]);
   1200 	} else {
   1201 		if (space)
   1202 			prchr(' ');
   1203 
   1204 		for (w = 1, n = base - 1; n >= 10; n /= 10)
   1205 			w++;
   1206 
   1207 		if (col + w > 69) {
   1208 			putchar('\\');
   1209 			putchar('\n');
   1210 			col = 0;
   1211 		}
   1212 		col += printf("%0*d", w, d);
   1213 	}
   1214 }
   1215 
   1216 static void
   1217 pushdigit(struct digit **l, int val)
   1218 {
   1219 	struct digit *it = emalloc(sizeof(*it));
   1220 
   1221 	it->next = *l;
   1222 	it->val = val;
   1223 	*l = it;
   1224 }
   1225 
   1226 static int
   1227 popdigit(struct digit **l)
   1228 {
   1229 	int val;
   1230 	struct digit *next, *it = *l;
   1231 
   1232 	if (it == NULL)
   1233 		return -1;
   1234 
   1235 	val = it->val;
   1236 	next = it->next;
   1237 	free(it);
   1238 	*l = next;
   1239 	return val;
   1240 }
   1241 
   1242 static void
   1243 printnum(Num *onum, int base)
   1244 {
   1245 	struct digit *sp;
   1246 	int sc, i, sign, n;
   1247 	Num *num, *inte, *frac, *opow;
   1248 
   1249 	col = 0;
   1250 	if (length(onum) == 0) {
   1251 		prchr('0');
   1252 		return;
   1253 	}
   1254 
   1255 	num = copy(onum);
   1256 	if ((sign = negative(num)) != 0)
   1257 		chsign(num);
   1258 
   1259 	sc = num->scale;
   1260 	if (num->scale % 2 == 1) {
   1261 		muln(num, 10);
   1262 		num->scale++;
   1263 	}
   1264 	inte = copy(num);
   1265 	rshift(inte, num->scale / 2);
   1266 	inte->scale = 0;
   1267 	frac = subnum(num, inte);
   1268 
   1269 	sp = NULL;
   1270 	for (i = 0; length(inte) > 0; ++i)
   1271 		pushdigit(&sp, divn(inte, base));
   1272 	if (sign)
   1273 		prchr('-');
   1274 	while (i-- > 0)
   1275 		printd(popdigit(&sp), base, 1);
   1276 	assert(sp == NULL);
   1277 
   1278 	if (num->scale == 0)
   1279 		goto ret;
   1280 
   1281         /*
   1282          * Print fractional part by repeated multiplication by base.
   1283          * We maintain the fraction as: frac / 10^scale
   1284          *
   1285          * Algorithm:
   1286          * 1. Multiply frac by base
   1287          * 2. Output integer part (frac / 10^scale)
   1288          * 3. Keep fractional part (frac % 10^scale)
   1289          */
   1290 	prchr('.');
   1291 
   1292 	opow = copy(&one);
   1293 	mul10(opow, num->scale);
   1294 
   1295 	for (n = 0; n < sc; ++n) {
   1296 		int d;
   1297 		Num *q, *rem;
   1298 
   1299 		muln(frac, base);
   1300 		q = divmod(frac, opow, &rem);
   1301 		d = first(q) ? peek(q) : 0;
   1302 		freenum(frac);
   1303 		freenum(q);
   1304 		frac = rem;
   1305 		printd(d, base, n > 0);
   1306 	}
   1307 	freenum(opow);
   1308 
   1309 ret:
   1310 	freenum(num);
   1311 	freenum(inte);
   1312 	freenum(frac);
   1313 }
   1314 
   1315 static int
   1316 moreinput(void)
   1317 {
   1318 	struct input *ip;
   1319 
   1320 repeat:
   1321 	if (!input)
   1322 		return 0;
   1323 
   1324 	if (input->buf != NULL && *input->s != '\0')
   1325 		return 1;
   1326 
   1327 	if (input->fp) {
   1328 		if (getline(&input->buf, &input->n, input->fp) >= 0) {
   1329 			input->s = input->buf;
   1330 			return 1;
   1331 		}
   1332 		if (ferror(input->fp)) {
   1333 			eprintf("reading from file:");
   1334 			exit(1);
   1335 		}
   1336 		fclose(input->fp);
   1337 	}
   1338 
   1339 	ip = input;
   1340 	input = ip->next;
   1341 	free(ip->buf);
   1342 	free(ip);
   1343 	goto repeat;
   1344 }
   1345 
   1346 static void
   1347 addinput(FILE *fp, char *s)
   1348 {
   1349 	struct input *ip;
   1350 
   1351 	assert((!fp && !s) == 0);
   1352 
   1353 	ip = emalloc(sizeof(*ip));
   1354 	ip->next = input;
   1355 	ip->fp = fp;
   1356 	ip->n = 0;
   1357 	ip->s = ip->buf = s;
   1358 	input = ip;
   1359 }
   1360 
   1361 static void
   1362 delinput(int cmd, int n)
   1363 {
   1364 	if (n < 0)
   1365 		error("Q command requires a number >= 0");
   1366 	while (n-- > 0) {
   1367 		if (cmd == 'Q' && !input->next)
   1368 			error("Q command argument exceeded string execution depth");
   1369 		if (input->fp)
   1370 			fclose(input->fp);
   1371 		free(input->buf);
   1372 		input = input->next;
   1373 		if (!input)
   1374 			exit(0);
   1375 	}
   1376 }
   1377 
   1378 static void
   1379 push(Val v)
   1380 {
   1381 	Val *p = emalloc(sizeof(Val));
   1382 
   1383 	*p = v;
   1384 	p->next = stack;
   1385 	stack = p;
   1386 }
   1387 
   1388 static void
   1389 needstack(int n)
   1390 {
   1391 	Val *vp;
   1392 
   1393 	for (vp = stack; n > 0 && vp; vp = vp->next)
   1394 		--n;
   1395 	if (n > 0)
   1396 		error("stack empty");
   1397 }
   1398 
   1399 static Val
   1400 pop(void)
   1401 {
   1402 	Val v;
   1403 
   1404 	if (!stack)
   1405 		error("stack empty");
   1406 	v = *stack;
   1407 	free(stack);
   1408 	stack = v.next;
   1409 
   1410 	return v;
   1411 }
   1412 
   1413 static Num *
   1414 popnum(void)
   1415 {
   1416 	Val v = pop();
   1417 
   1418 	if (v.type != NUM) {
   1419 		free(v.u.s);
   1420 		error("non-numeric value");
   1421 	}
   1422 	return v.u.n;
   1423 }
   1424 
   1425 static void
   1426 pushnum(Num *num)
   1427 {
   1428 	push((Val) {.type = NUM, .u.n = num});
   1429 }
   1430 
   1431 static void
   1432 pushstr(char *s)
   1433 {
   1434 	push((Val) {.type = STR, .u.s = s});
   1435 }
   1436 
   1437 static void
   1438 arith(Num *(*fn)(Num *, Num *))
   1439 {
   1440 	Num *a, *b, *c;
   1441 
   1442 	needstack(2);
   1443 	b = popnum();
   1444 	a = popnum();
   1445 	c = (*fn)(a, b);
   1446 	freenum(a);
   1447 	freenum(b);
   1448 	pushnum(c);
   1449 }
   1450 
   1451 static void
   1452 pushdivmod(void)
   1453 {
   1454 	Num *a, *b, *q, *rem;
   1455 
   1456 	needstack(2);
   1457 	b = popnum();
   1458 	a = popnum();
   1459 
   1460 	if (!divscale(a, b)) {
   1461 		q = copy(&zero);
   1462 		rem = copy(&zero);
   1463 	} else {
   1464 		q = divmod(a, b, &rem);
   1465 	}
   1466 
   1467 	pushnum(q);
   1468 	pushnum(rem);
   1469 	freenum(a);
   1470 	freenum(b);
   1471 }
   1472 
   1473 static int
   1474 popint(void)
   1475 {
   1476 	Num *num;
   1477 	int r = -1, n, d;
   1478 
   1479 	num = popnum();
   1480 	if (negative(num))
   1481 		goto ret;
   1482 
   1483 	/* discard fraction part */
   1484 	div10(num, num->scale);
   1485 
   1486 	n = 0;
   1487 	for (last(num); !begin(num); prev(num)) {
   1488 		if (n > INT_MAX / 100)
   1489 			goto ret;
   1490 		n *= 100;
   1491 		d = peek(num);
   1492 		if (n > INT_MAX - d)
   1493 			goto ret;
   1494 		n += d;
   1495 	}
   1496 	r = n;
   1497 
   1498 ret:
   1499 	freenum(num);
   1500 	return r;
   1501 }
   1502 
   1503 static void
   1504 pushint(int n)
   1505 {
   1506 	div_t dd;
   1507 	Num *num;
   1508 
   1509 	num = new(0);
   1510 	for ( ; n > 0; n = dd.quot) {
   1511 		dd = div(n, 100);
   1512 		wrdigit(num, dd.rem);
   1513 	}
   1514 	pushnum(num);
   1515 }
   1516 
   1517 static void
   1518 printval(Val v)
   1519 {
   1520 	if (v.type == STR)
   1521 		fputs(v.u.s, stdout);
   1522 	else
   1523 		printnum(v.u.n, obase);
   1524 }
   1525 
   1526 static Val
   1527 dupval(Val v)
   1528 {
   1529 	Val nv;
   1530 
   1531 	switch (nv.type = v.type) {
   1532 	case STR:
   1533 		nv.u.s = estrdup(v.u.s);
   1534 		break;
   1535 	case NUM:
   1536 		nv.u.n = copy(v.u.n);
   1537 		break;
   1538 	case NVAL:
   1539 		nv.type = NUM;
   1540 		nv.u.n = copy(&zero);
   1541 		break;
   1542 	}
   1543 
   1544 	return nv;
   1545 }
   1546 
   1547 static void
   1548 freeval(Val v)
   1549 {
   1550 	if (v.type == STR)
   1551 		free(v.u.s);
   1552 	else if (v.type == NUM)
   1553 		freenum(v.u.n);
   1554 }
   1555 
   1556 static void
   1557 dumpstack(void)
   1558 {
   1559 	Val *vp;
   1560 
   1561 	for (vp = stack; vp; vp = vp->next) {
   1562 		printval(*vp);
   1563 		putchar('\n');
   1564 	}
   1565 }
   1566 
   1567 static void
   1568 clearstack(void)
   1569 {
   1570 	Val *vp, *next;
   1571 
   1572 	for (vp = stack; vp; vp = next) {
   1573 		next = vp->next;
   1574 		freeval(*vp);
   1575 		free(vp);
   1576 	}
   1577 	stack = NULL;
   1578 }
   1579 
   1580 static void
   1581 dupstack(void)
   1582 {
   1583 	Val v;
   1584 
   1585 	push(v = pop());
   1586 	push(dupval(v));
   1587 }
   1588 
   1589 static void
   1590 deepstack(void)
   1591 {
   1592 	int n;
   1593 	Val *vp;
   1594 
   1595 	n = 0;
   1596 	for (vp = stack; vp; vp = vp->next) {
   1597 		if (n == INT_MAX)
   1598 			error("stack depth does not fit in a integer");
   1599 		++n;
   1600 	}
   1601 	pushint(n);
   1602 }
   1603 
   1604 static void
   1605 pushfrac(void)
   1606 {
   1607 	Val v = pop();
   1608 
   1609 	if (v.type == STR)
   1610 		pushint(0);
   1611 	else
   1612 		pushint(v.u.n->scale);
   1613 	freeval(v);
   1614 }
   1615 
   1616 static void
   1617 pushlen(void)
   1618 {
   1619 	int n;
   1620 	Num *num;
   1621 	Val v = pop();
   1622 
   1623 	if (v.type == STR) {
   1624 		n = strlen(v.u.s);
   1625 	} else {
   1626 		num = v.u.n;
   1627 		if (length(num) == 0) {
   1628 			n = 1;
   1629 		} else {
   1630 			n = length(num) * 2;
   1631 			n -= last(num) ? peek(num) < 10 : 0;
   1632 		}
   1633 	}
   1634 	pushint(n);
   1635 	freeval(v);
   1636 }
   1637 
   1638 static void
   1639 setibase(void)
   1640 {
   1641 	int n = popint();
   1642 
   1643 	if (n < 2 || n > 16)
   1644 		error("input base must be an integer between 2 and 16");
   1645 	ibase = n;
   1646 }
   1647 
   1648 static void
   1649 setobase(void)
   1650 {
   1651 	int n = popint();
   1652 
   1653 	if (n < 2)
   1654 		error("output base must be an integer greater than 1");
   1655 	obase = n;
   1656 }
   1657 
   1658 static char *
   1659 string(char *dst, int *np)
   1660 {
   1661 	int n, ch;
   1662 
   1663 	n = np ? *np : 0;
   1664 	for (;;) {
   1665 		ch = *input->s++;
   1666 
   1667 		switch (ch) {
   1668 		case '\0':
   1669 			if (!moreinput())
   1670 				exit(0);
   1671 			break;
   1672 		case '\\':
   1673 			if (*input->s == '[') {
   1674 				dst = erealloc(dst, n + 1);
   1675 				dst[n++] = *input->s++;
   1676 				break;
   1677 			}
   1678 			goto copy;
   1679 		case ']':
   1680 			if (!np) {
   1681 				dst = erealloc(dst, n + 1);
   1682 				dst[n] = '\0';
   1683 				return dst;
   1684 			}
   1685 		case '[':
   1686 		default:
   1687 		copy:
   1688 			dst = erealloc(dst, n + 1);
   1689 			dst[n++] = ch;
   1690 			if (ch == '[')
   1691 				dst = string(dst, &n);
   1692 			if (ch == ']') {
   1693 				*np = n;
   1694 				return dst;
   1695 			}
   1696 		}
   1697 	}
   1698 }
   1699 
   1700 static void
   1701 setscale(void)
   1702 {
   1703 	int n = popint();
   1704 
   1705 	if (n < 0)
   1706 		error("scale must be a nonnegative integer");
   1707 	scale = n;
   1708 }
   1709 
   1710 static unsigned
   1711 hash(char *name)
   1712 {
   1713 	int c;
   1714 	unsigned h = 5381;
   1715 
   1716 	while (c = *name++)
   1717 		h = h*33 ^ c;
   1718 
   1719 	return h;
   1720 }
   1721 
   1722 static struct reg *
   1723 lookup(char *name)
   1724 {
   1725 	struct reg *rp;
   1726 	int h = hash(name) & HASHSIZ-1;
   1727 
   1728 	for (rp = htbl[h]; rp; rp = rp->next) {
   1729 		if (strcmp(name, rp->name) == 0)
   1730 			return rp;
   1731 	}
   1732 
   1733 	rp = emalloc(sizeof(*rp));
   1734 	rp->next = htbl[h];
   1735 	htbl[h] = rp;
   1736 	rp->name = estrdup(name);
   1737 
   1738 	rp->val.type = NVAL;
   1739 	rp->val.next = NULL;
   1740 
   1741 	rp->ary.n = 0;
   1742 	rp->ary.buf = NULL;
   1743 	rp->ary.next = NULL;
   1744 
   1745 	return rp;
   1746 }
   1747 
   1748 static char *
   1749 regname(void)
   1750 {
   1751 	int delim, ch;
   1752 	char *s;
   1753 	static char name[REGSIZ];
   1754 
   1755 	ch = *input->s++;
   1756 	if (!iflag || ch != '<' && ch != '"') {
   1757 		name[0] = ch;
   1758 		name[1] = '\0';
   1759 		return name;
   1760 	}
   1761 
   1762 	if ((delim = ch) == '<')
   1763 		delim = '>';
   1764 
   1765 	for (s = name; s < &name[REGSIZ]; ++s) {
   1766 		ch = *input->s++;
   1767 		if (ch == '\0' ||  ch == delim) {
   1768 			*s = '\0';
   1769 			if (ch == '>') {
   1770 				name[0] = atoi(name);
   1771 				name[1] = '\0';
   1772 			}
   1773 			return name;
   1774 		}
   1775 		*s = ch;
   1776 	}
   1777 
   1778 	error("identifier too long");
   1779 }
   1780 
   1781 static void
   1782 popreg(void)
   1783 {
   1784 	int i;
   1785 	Val *vnext;
   1786 	struct ary *anext;
   1787 	char *s = regname();
   1788 	struct reg *rp = lookup(s);
   1789 
   1790 	if (rp->val.type == NVAL)
   1791 		error("stack register '%s' (%o) is empty", s, s[0]);
   1792 
   1793 	push(rp->val);
   1794 	vnext = rp->val.next;
   1795 	if (!vnext) {
   1796 		rp->val.type = NVAL;
   1797 	} else {
   1798 		rp->val = *vnext;
   1799 		free(vnext);
   1800 	}
   1801 
   1802 	for (i = 0; i < rp->ary.n; ++i)
   1803 		freeval(rp->ary.buf[i]);
   1804 	free(rp->ary.buf);
   1805 
   1806 	anext = rp->ary.next;
   1807 	if (!anext) {
   1808 		rp->ary.n = 0;
   1809 		rp->ary.buf = NULL;
   1810 	} else {
   1811 		rp->ary = *anext;
   1812 		free(anext);
   1813 	}
   1814 }
   1815 
   1816 static void
   1817 pushreg(void)
   1818 {
   1819 	Val v;
   1820 	Val *vp;
   1821 	struct ary *ap;
   1822 	struct reg *rp = lookup(regname());
   1823 
   1824 	v = pop();
   1825 
   1826 	vp = emalloc(sizeof(Val));
   1827 	*vp = rp->val;
   1828 	rp->val = v;
   1829 	rp->val.next = vp;
   1830 
   1831 	ap = emalloc(sizeof(struct ary));
   1832 	*ap = rp->ary;
   1833 	rp->ary.n = 0;
   1834 	rp->ary.buf = NULL;
   1835 	rp->ary.next = ap;
   1836 }
   1837 
   1838 static Val *
   1839 aryidx(void)
   1840 {
   1841 	int n;
   1842 	int i;
   1843 	Val *vp;
   1844 	struct reg *rp = lookup(regname());
   1845 	struct ary *ap = &rp->ary;
   1846 
   1847 	n = popint();
   1848 	if (n < 0)
   1849 		error("array index must fit in a positive integer");
   1850 
   1851 	if (n >= ap->n) {
   1852 		ap->buf = ereallocarray(ap->buf, n+1, sizeof(Val));
   1853 		for (i = ap->n; i <= n; ++i)
   1854 			ap->buf[i].type = NVAL;
   1855 		ap->n = n + 1;
   1856 	}
   1857 	return &ap->buf[n];
   1858 }
   1859 
   1860 static void
   1861 aryget(void)
   1862 {
   1863 	Val *vp = aryidx();
   1864 
   1865 	push(dupval(*vp));
   1866 }
   1867 
   1868 static void
   1869 aryset(void)
   1870 {
   1871 	Val val, *vp = aryidx();
   1872 
   1873 	val = pop();
   1874 	freeval(*vp);
   1875 	*vp = val;
   1876 }
   1877 
   1878 static void
   1879 execmacro(void)
   1880 {
   1881 	int ch;
   1882 	Val v = pop();
   1883 
   1884 	assert(v.type != NVAL);
   1885 	if (v.type == NUM) {
   1886 		push(v);
   1887 		return;
   1888 	}
   1889 
   1890 	if (input->fp) {
   1891 		addinput(NULL, v.u.s);
   1892 		return;
   1893 	}
   1894 
   1895 	/* check for tail recursion */
   1896 	for (ch = *input->s; ch > 0 && ch < UCHAR_MAX; ch = *input->s) {
   1897 		if (!isspace(ch))
   1898 			break;
   1899 		++input->s;
   1900 	}
   1901 
   1902 	if (ch == '\0') {
   1903 		free(input->buf);
   1904 		input->buf = input->s = v.u.s;
   1905 		return;
   1906 	}
   1907 
   1908 	addinput(NULL, v.u.s);
   1909 }
   1910 
   1911 static void
   1912 relational(int ch)
   1913 {
   1914 	int r;
   1915 	char *s;
   1916 	Num *a, *b;
   1917 	struct reg *rp = lookup(regname());
   1918 
   1919 	needstack(2);
   1920 	a = popnum();
   1921 	b = popnum();
   1922 	r = cmpnum(a, b);
   1923 	freenum(a);
   1924 	freenum(b);
   1925 
   1926 	switch (ch) {
   1927 	case '>':
   1928 		r = r > 0;
   1929 		break;
   1930 	case '<':
   1931 		r = r < 0;
   1932 		break;
   1933 	case '=':
   1934 		r = r == 0;
   1935 		break;
   1936 	case LE:
   1937 		r = r <= 0;
   1938 		break;
   1939 	case GE:
   1940 		r = r >= 0;
   1941 		break;
   1942 	case NE:
   1943 		r = r != 0;
   1944 		break;
   1945 	default:
   1946 		abort();
   1947 	}
   1948 
   1949 	if (!r)
   1950 		return;
   1951 
   1952 	push(dupval(rp->val));
   1953 	execmacro();
   1954 }
   1955 
   1956 static void
   1957 printbytes(void)
   1958 {
   1959 	Num *num;
   1960 	Val v = pop();
   1961 
   1962 	if (v.type == STR) {
   1963 		fputs(v.u.s, stdout);
   1964 	} else {
   1965 		num = v.u.n;
   1966 		div10(num, num->scale);
   1967 		num->scale = 0;
   1968 		printnum(num, 100);
   1969 	}
   1970 	freeval(v);
   1971 }
   1972 
   1973 static void
   1974 eval(void)
   1975 {
   1976 	int ch;
   1977 	char *s;
   1978 	Num *num;
   1979 	size_t siz;
   1980 	Val v1, v2;
   1981 	struct reg *rp;
   1982 
   1983 	if (setjmp(env))
   1984 		return;
   1985 
   1986 	for (s = input->s; (ch = *s) != '\0'; ++s) {
   1987 		if (ch < 0 || ch > UCHAR_MAX || !isspace(ch))
   1988 			break;
   1989 	}
   1990 	input->s = s + (ch != '\0');
   1991 
   1992 	switch (ch) {
   1993 	case '\0':
   1994 		break;
   1995 	case 'n':
   1996 		v1 = pop();
   1997 		printval(v1);
   1998 		freeval(v1);
   1999 		break;
   2000 	case 'p':
   2001 		v1 = pop();
   2002 		printval(v1);
   2003 		putchar('\n');
   2004 		push(v1);
   2005 		break;
   2006 	case 'P':
   2007 		printbytes();
   2008 		break;
   2009 	case 'f':
   2010 		dumpstack();
   2011 		break;
   2012 	case '+':
   2013 		arith(addnum);
   2014 		break;
   2015 	case '-':
   2016 		arith(subnum);
   2017 		break;
   2018 	case '*':
   2019 		arith(mulnum);
   2020 		break;
   2021 	case '/':
   2022 		arith(divnum);
   2023 		break;
   2024 	case '%':
   2025 		arith(modnum);
   2026 		break;
   2027 	case '^':
   2028 		arith(expnum);
   2029 		break;
   2030 	case '~':
   2031 		pushdivmod();
   2032 		break;
   2033 	case 'v':
   2034 		num = popnum();
   2035 		pushnum(sqrtnum(num));
   2036 		freenum(num);
   2037 		break;
   2038 	case 'c':
   2039 		clearstack();
   2040 		break;
   2041 	case 'd':
   2042 		dupstack();
   2043 		break;
   2044 	case 'r':
   2045 		needstack(2);
   2046 		v1 = pop();
   2047 		v2 = pop();
   2048 		push(v1);
   2049 		push(v2);
   2050 		break;
   2051 	case 'S':
   2052 		pushreg();
   2053 		break;
   2054 	case 'L':
   2055 		popreg();
   2056 		break;
   2057 	case 's':
   2058 		rp = lookup(regname());
   2059 		freeval(rp->val);
   2060 		rp->val = pop();
   2061 		break;
   2062 	case 'l':
   2063 		rp = lookup(regname());
   2064 		push(dupval(rp->val));
   2065 		break;
   2066 	case 'i':
   2067 		setibase();
   2068 		break;
   2069 	case 'o':
   2070 		setobase();
   2071 		break;
   2072 	case 'k':
   2073 		setscale();
   2074 		break;
   2075 	case 'I':
   2076 		pushint(ibase);
   2077 		break;
   2078 	case 'O':
   2079 		pushint(obase);
   2080 		break;
   2081 	case 'K':
   2082 		pushint(scale);
   2083 		break;
   2084 	case '[':
   2085 		pushstr(string(NULL, NULL));
   2086 		break;
   2087 	case 'x':
   2088 		execmacro();
   2089 		break;
   2090 	case '!':
   2091 		switch (*input->s++) {
   2092 		case '<':
   2093 			ch = GE;
   2094 			break;
   2095 		case '>':
   2096 			ch = LE;
   2097 			break;
   2098 		case '=':
   2099 			ch = NE;
   2100 			break;
   2101 		default:
   2102 			system(input->s-1);
   2103 			goto discard;
   2104 		}
   2105 	case '>':
   2106 	case '<':
   2107 	case '=':
   2108 		relational(ch);
   2109 		break;
   2110 	case '?':
   2111 		s = NULL;
   2112 		if (getline(&s, &siz, stdin) > 0) {
   2113 			pushstr(s);
   2114 		} else {
   2115 			free(s);
   2116 			if (ferror(stdin))
   2117 				eprintf("reading from file\n");
   2118 		}
   2119 		break;
   2120 	case 'q':
   2121 		delinput('q', 2);
   2122 		break;
   2123 	case 'Q':
   2124 		delinput('Q', popint());
   2125 		break;
   2126 	case 'Z':
   2127 		pushlen();
   2128 		break;
   2129 	case 'X':
   2130 		pushfrac();
   2131 		break;
   2132 	case 'z':
   2133 		deepstack();
   2134 		break;
   2135 	case '#':
   2136 	discard:
   2137 		while (*input->s)
   2138 			++input->s;
   2139 		break;
   2140 	case ':':
   2141 		aryset();
   2142 		break;
   2143 	case ';':
   2144 		aryget();
   2145 		break;
   2146 	default:
   2147 		if (!strchr(digits, ch))
   2148 			error("'%c' (%#o) unimplemented", ch, ch);
   2149 	case '_':
   2150 		--input->s;
   2151 		pushnum(tonum());
   2152 		break;
   2153 	}
   2154 }
   2155 
   2156 static void
   2157 dc(char *fname)
   2158 {
   2159 	FILE *fp;
   2160 
   2161 	if (strcmp(fname, "-") == 0) {
   2162 		fp = stdin;
   2163 	} else {
   2164 		if ((fp = fopen(fname, "r")) == NULL)
   2165 			eprintf("opening '%s':", fname);
   2166 	}
   2167 	addinput(fp, NULL);
   2168 
   2169 	while (moreinput())
   2170 		eval();
   2171 
   2172 	fclose(fp);
   2173 	free(input);
   2174 	input = NULL;
   2175 }
   2176 
   2177 static void
   2178 usage(void)
   2179 {
   2180 	eprintf("usage: dc [-i] [file ...]\n");
   2181 }
   2182 
   2183 int
   2184 main(int argc, char *argv[])
   2185 {
   2186 	ARGBEGIN {
   2187 	case 'i':
   2188 		iflag = 1;
   2189 		break;
   2190 	default:
   2191 		usage();
   2192 	} ARGEND
   2193 
   2194 	while (*argv)
   2195 		dc(*argv++);
   2196 	dc("-");
   2197 
   2198 	return 0;
   2199 }