xref: /openbsd/usr.bin/dc/bcode.c (revision 4cfece93)
1 /*	$OpenBSD: bcode.c,v 1.62 2017/12/29 08:16:55 otto Exp $	*/
2 
3 /*
4  * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <err.h>
20 #include <limits.h>
21 #include <signal.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "extern.h"
27 
28 /* #define	DEBUGGING */
29 
30 #define MAX_ARRAY_INDEX		2048
31 #define READSTACK_SIZE		8
32 
33 #define NO_ELSE			-2	/* -1 is EOF */
34 #define REG_ARRAY_SIZE_SMALL	(UCHAR_MAX + 1)
35 #define REG_ARRAY_SIZE_BIG	(UCHAR_MAX + 1 + USHRT_MAX + 1)
36 
37 struct bmachine {
38 	struct stack		stack;
39 	u_int			scale;
40 	u_int			obase;
41 	u_int			ibase;
42 	size_t			readsp;
43 	bool			extended_regs;
44 	size_t			reg_array_size;
45 	struct stack		*reg;
46 	volatile sig_atomic_t	interrupted;
47 	struct source		*readstack;
48 	size_t			readstack_sz;
49 	BN_CTX			*ctx;
50 };
51 
52 static struct bmachine	bmachine;
53 static void sighandler(int);
54 
55 static __inline int	readch(void);
56 static __inline void	unreadch(void);
57 static __inline char	*readline(void);
58 static __inline void	src_free(void);
59 
60 static __inline u_int	max(u_int, u_int);
61 static u_long		get_ulong(struct number *);
62 
63 static __inline void	push_number(struct number *);
64 static __inline void	push_string(char *);
65 static __inline void	push(struct value *);
66 static __inline struct value *tos(void);
67 static __inline struct number	*pop_number(void);
68 static __inline char	*pop_string(void);
69 static void		clear_stack(void);
70 static void		print_tos(void);
71 static void		print_err(void);
72 static void		pop_print(void);
73 static void		pop_printn(void);
74 static void		print_stack(void);
75 static void		dup(void);
76 static void		swap(void);
77 static void		drop(void);
78 
79 static void		get_scale(void);
80 static void		set_scale(void);
81 static void		get_obase(void);
82 static void		set_obase(void);
83 static void		get_ibase(void);
84 static void		set_ibase(void);
85 static void		stackdepth(void);
86 static void		push_scale(void);
87 static u_int		count_digits(const struct number *);
88 static void		num_digits(void);
89 static void		to_ascii(void);
90 static void		push_line(void);
91 static void		comment(void);
92 static void		badd(void);
93 static void		bsub(void);
94 static void		bmul(void);
95 static void		bdiv(void);
96 static void		bmod(void);
97 static void		bdivmod(void);
98 static void		bexp(void);
99 static void		bsqrt(void);
100 static void		not(void);
101 static void		equal_numbers(void);
102 static void		less_numbers(void);
103 static void		lesseq_numbers(void);
104 static void		equal(void);
105 static void		less(void);
106 static void		greater(void);
107 static void		not_compare(void);
108 static bool		compare_numbers(enum bcode_compare, struct number *,
109 			    struct number *);
110 static void		compare(enum bcode_compare);
111 static int		readreg(void);
112 static void		load(void);
113 static void		store(void);
114 static void		load_stack(void);
115 static void		store_stack(void);
116 static void		load_array(void);
117 static void		store_array(void);
118 static void		nop(void);
119 static void		quit(void);
120 static void		quitN(void);
121 static void		skipN(void);
122 static void		skip_until_mark(void);
123 static void		parse_number(void);
124 static void		unknown(void);
125 static void		eval_string(char *);
126 static void		eval_line(void);
127 static void		eval_tos(void);
128 
129 
130 typedef void		(*opcode_function)(void);
131 
132 struct jump_entry {
133 	u_char		ch;
134 	opcode_function	f;
135 };
136 
137 
138 static opcode_function jump_table[UCHAR_MAX + 1];
139 
140 static const struct jump_entry jump_table_data[] = {
141 	{ ' ',	nop		},
142 	{ '!',	not_compare	},
143 	{ '#',	comment		},
144 	{ '%',	bmod		},
145 	{ '(',	less_numbers	},
146 	{ '*',	bmul		},
147 	{ '+',	badd		},
148 	{ '-',	bsub		},
149 	{ '.',	parse_number	},
150 	{ '/',	bdiv		},
151 	{ '0',	parse_number	},
152 	{ '1',	parse_number	},
153 	{ '2',	parse_number	},
154 	{ '3',	parse_number	},
155 	{ '4',	parse_number	},
156 	{ '5',	parse_number	},
157 	{ '6',	parse_number	},
158 	{ '7',	parse_number	},
159 	{ '8',	parse_number	},
160 	{ '9',	parse_number	},
161 	{ ':',	store_array	},
162 	{ ';',	load_array	},
163 	{ '<',	less		},
164 	{ '=',	equal		},
165 	{ '>',	greater		},
166 	{ '?',	eval_line	},
167 	{ 'A',	parse_number	},
168 	{ 'B',	parse_number	},
169 	{ 'C',	parse_number	},
170 	{ 'D',	parse_number	},
171 	{ 'E',	parse_number	},
172 	{ 'F',	parse_number	},
173 	{ 'G',	equal_numbers	},
174 	{ 'I',	get_ibase	},
175 	{ 'J',	skipN		},
176 	{ 'K',	get_scale	},
177 	{ 'L',	load_stack	},
178 	{ 'M',	nop		},
179 	{ 'N',	not		},
180 	{ 'O',	get_obase	},
181 	{ 'P',	pop_print	},
182 	{ 'Q',	quitN		},
183 	{ 'R',	drop		},
184 	{ 'S',	store_stack	},
185 	{ 'X',	push_scale	},
186 	{ 'Z',	num_digits	},
187 	{ '[',	push_line	},
188 	{ '\f',	nop		},
189 	{ '\n',	nop		},
190 	{ '\r',	nop		},
191 	{ '\t',	nop		},
192 	{ '^',	bexp		},
193 	{ '_',	parse_number	},
194 	{ 'a',	to_ascii	},
195 	{ 'c',	clear_stack	},
196 	{ 'd',	dup		},
197 	{ 'e',	print_err	},
198 	{ 'f',	print_stack	},
199 	{ 'i',	set_ibase	},
200 	{ 'k',	set_scale	},
201 	{ 'l',	load		},
202 	{ 'n',	pop_printn	},
203 	{ 'o',	set_obase	},
204 	{ 'p',	print_tos	},
205 	{ 'q',	quit		},
206 	{ 'r',	swap		},
207 	{ 's',	store		},
208 	{ 'v',	bsqrt		},
209 	{ 'x',	eval_tos	},
210 	{ 'z',	stackdepth	},
211 	{ '{',	lesseq_numbers	},
212 	{ '~',	bdivmod		}
213 };
214 
215 #ifndef nitems
216 #define nitems(a)	(sizeof((a)) / sizeof((a)[0]))
217 #endif
218 
219 /* ARGSUSED */
220 static void
221 sighandler(int ignored)
222 {
223 	bmachine.interrupted = true;
224 }
225 
226 void
227 init_bmachine(bool extended_registers)
228 {
229 	int i;
230 
231 	bmachine.ctx = BN_CTX_new();
232 	bn_checkp(bmachine.ctx);
233 
234 	bmachine.extended_regs = extended_registers;
235 	bmachine.reg_array_size = bmachine.extended_regs ?
236 	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
237 
238 	bmachine.reg = calloc(bmachine.reg_array_size,
239 	    sizeof(bmachine.reg[0]));
240 	if (bmachine.reg == NULL)
241 		err(1, NULL);
242 
243 	for (i = 0; i < nitems(jump_table); i++)
244 		jump_table[i] = unknown;
245 
246 	for (i = 0; i < nitems(jump_table_data); i++) {
247 		if ((unsigned int)jump_table_data[i].ch >= nitems(jump_table))
248 			errx(1, "opcode '%c' overflows jump table",
249 			    jump_table_data[i].ch);
250 		if (jump_table[jump_table_data[i].ch] != unknown)
251 			errx(1, "opcode '%c' already assigned",
252 			    jump_table_data[i].ch);
253 		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
254 	}
255 
256 	stack_init(&bmachine.stack);
257 
258 	for (i = 0; i < bmachine.reg_array_size; i++)
259 		stack_init(&bmachine.reg[i]);
260 
261 	bmachine.readstack_sz = READSTACK_SIZE;
262 	bmachine.readstack = calloc(sizeof(struct source),
263 	    bmachine.readstack_sz);
264 	if (bmachine.readstack == NULL)
265 		err(1, NULL);
266 	bmachine.obase = bmachine.ibase = 10;
267 	(void)signal(SIGINT, sighandler);
268 }
269 
270 u_int
271 bmachine_scale(void)
272 {
273 	return bmachine.scale;
274 }
275 
276 /* Reset the things needed before processing a (new) file */
277 void
278 reset_bmachine(struct source *src)
279 {
280 	bmachine.readsp = 0;
281 	bmachine.readstack[0] = *src;
282 }
283 
284 static __inline int
285 readch(void)
286 {
287 	struct source *src = &bmachine.readstack[bmachine.readsp];
288 
289 	return src->vtable->readchar(src);
290 }
291 
292 static __inline void
293 unreadch(void)
294 {
295 	struct source *src = &bmachine.readstack[bmachine.readsp];
296 
297 	src->vtable->unreadchar(src);
298 }
299 
300 static __inline char *
301 readline(void)
302 {
303 	struct source *src = &bmachine.readstack[bmachine.readsp];
304 
305 	return src->vtable->readline(src);
306 }
307 
308 static __inline void
309 src_free(void)
310 {
311 	struct source *src = &bmachine.readstack[bmachine.readsp];
312 
313 	src->vtable->free(src);
314 }
315 
316 #ifdef DEBUGGING
317 void
318 pn(const char *str, const struct number *n)
319 {
320 	char *p = BN_bn2dec(n->number);
321 	if (p == NULL)
322 		err(1, "BN_bn2dec failed");
323 	(void)fputs(str, stderr);
324 	(void)fprintf(stderr, " %s (%u)\n" , p, n->scale);
325 	OPENSSL_free(p);
326 }
327 
328 void
329 pbn(const char *str, const BIGNUM *n)
330 {
331 	char *p = BN_bn2dec(n);
332 	if (p == NULL)
333 		err(1, "BN_bn2dec failed");
334 	(void)fputs(str, stderr);
335 	(void)fprintf(stderr, " %s\n", p);
336 	OPENSSL_free(p);
337 }
338 
339 #endif
340 
341 static __inline u_int
342 max(u_int a, u_int b)
343 {
344 	return a > b ? a : b;
345 }
346 
347 static unsigned long factors[] = {
348 	0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
349 	100000000, 1000000000
350 };
351 
352 void
353 scale_number(BIGNUM *n, int s)
354 {
355 	int abs_scale;
356 
357 	if (s == 0)
358 		return;
359 
360 	abs_scale = s > 0 ? s : -s;
361 
362 	if (abs_scale < nitems(factors)) {
363 		if (s > 0)
364 			bn_check(BN_mul_word(n, factors[abs_scale]));
365 		else
366 			(void)BN_div_word(n, factors[abs_scale]);
367 	} else {
368 		BIGNUM *a, *p;
369 
370 		a = BN_new();
371 		bn_checkp(a);
372 		p = BN_new();
373 		bn_checkp(p);
374 
375 		bn_check(BN_set_word(a, 10));
376 		bn_check(BN_set_word(p, abs_scale));
377 		bn_check(BN_exp(a, a, p, bmachine.ctx));
378 		if (s > 0)
379 			bn_check(BN_mul(n, n, a, bmachine.ctx));
380 		else
381 			bn_check(BN_div(n, NULL, n, a, bmachine.ctx));
382 		BN_free(a);
383 		BN_free(p);
384 	}
385 }
386 
387 void
388 split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
389 {
390 	u_long rem;
391 
392 	bn_checkp(BN_copy(i, n->number));
393 
394 	if (n->scale == 0) {
395 		if (f != NULL)
396 			bn_check(BN_set_word(f, 0));
397 	} else if (n->scale < nitems(factors)) {
398 		rem = BN_div_word(i, factors[n->scale]);
399 		if (f != NULL)
400 			bn_check(BN_set_word(f, rem));
401 	} else {
402 		BIGNUM *a, *p;
403 
404 		a = BN_new();
405 		bn_checkp(a);
406 		p = BN_new();
407 		bn_checkp(p);
408 
409 		bn_check(BN_set_word(a, 10));
410 		bn_check(BN_set_word(p, n->scale));
411 		bn_check(BN_exp(a, a, p, bmachine.ctx));
412 		bn_check(BN_div(i, f, n->number, a, bmachine.ctx));
413 		BN_free(a);
414 		BN_free(p);
415 	}
416 }
417 
418 void
419 normalize(struct number *n, u_int s)
420 {
421 	scale_number(n->number, s - n->scale);
422 	n->scale = s;
423 }
424 
425 static u_long
426 get_ulong(struct number *n)
427 {
428 	normalize(n, 0);
429 	return BN_get_word(n->number);
430 }
431 
432 void
433 negate(struct number *n)
434 {
435 	BN_set_negative(n->number, !BN_is_negative(n->number));
436 }
437 
438 static __inline void
439 push_number(struct number *n)
440 {
441 	stack_pushnumber(&bmachine.stack, n);
442 }
443 
444 static __inline void
445 push_string(char *string)
446 {
447 	stack_pushstring(&bmachine.stack, string);
448 }
449 
450 static __inline void
451 push(struct value *v)
452 {
453 	stack_push(&bmachine.stack, v);
454 }
455 
456 static __inline struct value *
457 tos(void)
458 {
459 	return stack_tos(&bmachine.stack);
460 }
461 
462 static __inline struct value *
463 pop(void)
464 {
465 	return stack_pop(&bmachine.stack);
466 }
467 
468 static __inline struct number *
469 pop_number(void)
470 {
471 	return stack_popnumber(&bmachine.stack);
472 }
473 
474 static __inline char *
475 pop_string(void)
476 {
477 	return stack_popstring(&bmachine.stack);
478 }
479 
480 static void
481 clear_stack(void)
482 {
483 	stack_clear(&bmachine.stack);
484 }
485 
486 static void
487 print_stack(void)
488 {
489 	stack_print(stdout, &bmachine.stack, "", bmachine.obase);
490 }
491 
492 static void
493 print_tos(void)
494 {
495 	struct value *value = tos();
496 	if (value != NULL) {
497 		print_value(stdout, value, "", bmachine.obase);
498 		(void)putchar('\n');
499 	} else
500 		warnx("stack empty");
501 }
502 
503 static void
504 print_err(void)
505 {
506 	struct value *value = tos();
507 	if (value != NULL) {
508 		print_value(stderr, value, "", bmachine.obase);
509 		(void)putc('\n', stderr);
510 	} else
511 		warnx("stack empty");
512 }
513 
514 static void
515 pop_print(void)
516 {
517 	struct value *value = pop();
518 
519 	if (value != NULL) {
520 		switch (value->type) {
521 		case BCODE_NONE:
522 			break;
523 		case BCODE_NUMBER:
524 			normalize(value->u.num, 0);
525 			print_ascii(stdout, value->u.num);
526 			(void)fflush(stdout);
527 			break;
528 		case BCODE_STRING:
529 			(void)fputs(value->u.string, stdout);
530 			(void)fflush(stdout);
531 			break;
532 		}
533 		stack_free_value(value);
534 	}
535 }
536 
537 static void
538 pop_printn(void)
539 {
540 	struct value *value = pop();
541 
542 	if (value != NULL) {
543 		print_value(stdout, value, "", bmachine.obase);
544 		(void)fflush(stdout);
545 		stack_free_value(value);
546 	}
547 }
548 
549 static void
550 dup(void)
551 {
552 	stack_dup(&bmachine.stack);
553 }
554 
555 static void
556 swap(void)
557 {
558 	stack_swap(&bmachine.stack);
559 }
560 
561 static void
562 drop(void)
563 {
564 	struct value *v = pop();
565 	if (v != NULL)
566 		stack_free_value(v);
567 }
568 
569 static void
570 get_scale(void)
571 {
572 	struct number	*n;
573 
574 	n = new_number();
575 	bn_check(BN_set_word(n->number, bmachine.scale));
576 	push_number(n);
577 }
578 
579 static void
580 set_scale(void)
581 {
582 	struct number	*n;
583 	u_long		scale;
584 
585 	n = pop_number();
586 	if (n != NULL) {
587 		if (BN_is_negative(n->number))
588 			warnx("scale must be a nonnegative number");
589 		else {
590 			scale = get_ulong(n);
591 			if (scale != BN_MASK2 && scale <= UINT_MAX)
592 				bmachine.scale = (u_int)scale;
593 			else
594 				warnx("scale too large");
595 		}
596 		free_number(n);
597 	}
598 }
599 
600 static void
601 get_obase(void)
602 {
603 	struct number	*n;
604 
605 	n = new_number();
606 	bn_check(BN_set_word(n->number, bmachine.obase));
607 	push_number(n);
608 }
609 
610 static void
611 set_obase(void)
612 {
613 	struct number	*n;
614 	u_long		base;
615 
616 	n = pop_number();
617 	if (n != NULL) {
618 		base = get_ulong(n);
619 		if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
620 			bmachine.obase = (u_int)base;
621 		else
622 			warnx("output base must be a number greater than 1");
623 		free_number(n);
624 	}
625 }
626 
627 static void
628 get_ibase(void)
629 {
630 	struct number *n;
631 
632 	n = new_number();
633 	bn_check(BN_set_word(n->number, bmachine.ibase));
634 	push_number(n);
635 }
636 
637 static void
638 set_ibase(void)
639 {
640 	struct number	*n;
641 	u_long		base;
642 
643 	n = pop_number();
644 	if (n != NULL) {
645 		base = get_ulong(n);
646 		if (base != BN_MASK2 && 2 <= base && base <= 16)
647 			bmachine.ibase = (u_int)base;
648 		else
649 			warnx("input base must be a number between 2 and 16 "
650 			    "(inclusive)");
651 		free_number(n);
652 	}
653 }
654 
655 static void
656 stackdepth(void)
657 {
658 	size_t i;
659 	struct number *n;
660 
661 	i = stack_size(&bmachine.stack);
662 	n = new_number();
663 	bn_check(BN_set_word(n->number, i));
664 	push_number(n);
665 }
666 
667 static void
668 push_scale(void)
669 {
670 	struct value	*value;
671 	u_int		scale = 0;
672 	struct number	*n;
673 
674 	value = pop();
675 	if (value != NULL) {
676 		switch (value->type) {
677 		case BCODE_NONE:
678 			return;
679 		case BCODE_NUMBER:
680 			scale = value->u.num->scale;
681 			break;
682 		case BCODE_STRING:
683 			break;
684 		}
685 		stack_free_value(value);
686 		n = new_number();
687 		bn_check(BN_set_word(n->number, scale));
688 		push_number(n);
689 	}
690 }
691 
692 static u_int
693 count_digits(const struct number *n)
694 {
695 	BIGNUM		*int_part, *a, *p;
696 	uint		d;
697 	const uint64_t	c = 1292913986; /* floor(2^32 * log_10(2)) */
698 	int		bits;
699 
700 	if (BN_is_zero(n->number))
701 		return n->scale;
702 
703 	int_part = BN_new();
704 	bn_checkp(int_part);
705 
706 	split_number(n, int_part, NULL);
707 	bits = BN_num_bits(int_part);
708 
709 	if (bits == 0)
710 		d = 0;
711 	else {
712 		/*
713 		 * Estimate number of decimal digits based on number of bits.
714 		 * Divide 2^32 factor out by shifting
715 		 */
716 		d = (c * bits) >> 32;
717 
718 		/* If close to a possible rounding error fix if needed */
719 		if (d != (c * (bits - 1)) >> 32) {
720 			a = BN_new();
721 			bn_checkp(a);
722 			p = BN_new();
723 			bn_checkp(p);
724 
725 			bn_check(BN_set_word(a, 10));
726 			bn_check(BN_set_word(p, d));
727 			bn_check(BN_exp(a, a, p, bmachine.ctx));
728 
729 			if (BN_ucmp(int_part, a) >= 0)
730 				d++;
731 
732 			BN_free(a);
733 			BN_free(p);
734 		} else
735 			d++;
736 	}
737 
738 	BN_free(int_part);
739 
740 	return d + n->scale;
741 }
742 
743 static void
744 num_digits(void)
745 {
746 	struct value	*value;
747 	size_t		digits;
748 	struct number	*n = NULL;
749 
750 	value = pop();
751 	if (value != NULL) {
752 		switch (value->type) {
753 		case BCODE_NONE:
754 			return;
755 		case BCODE_NUMBER:
756 			digits = count_digits(value->u.num);
757 			n = new_number();
758 			bn_check(BN_set_word(n->number, digits));
759 			break;
760 		case BCODE_STRING:
761 			digits = strlen(value->u.string);
762 			n = new_number();
763 			bn_check(BN_set_word(n->number, digits));
764 			break;
765 		}
766 		stack_free_value(value);
767 		push_number(n);
768 	}
769 }
770 
771 static void
772 to_ascii(void)
773 {
774 	char		str[2];
775 	struct value	*value;
776 	struct number	*n;
777 
778 	value = pop();
779 	if (value != NULL) {
780 		str[1] = '\0';
781 		switch (value->type) {
782 		case BCODE_NONE:
783 			return;
784 		case BCODE_NUMBER:
785 			n = value->u.num;
786 			normalize(n, 0);
787 			if (BN_num_bits(n->number) > 8)
788 				bn_check(BN_mask_bits(n->number, 8));
789 			str[0] = (char)BN_get_word(n->number);
790 			break;
791 		case BCODE_STRING:
792 			str[0] = value->u.string[0];
793 			break;
794 		}
795 		stack_free_value(value);
796 		push_string(bstrdup(str));
797 	}
798 }
799 
800 static int
801 readreg(void)
802 {
803 	int idx, ch1, ch2;
804 
805 	idx = readch();
806 	if (idx == 0xff && bmachine.extended_regs) {
807 		ch1 = readch();
808 		ch2 = readch();
809 		if (ch1 == EOF || ch2 == EOF) {
810 			warnx("unexpected eof");
811 			idx = -1;
812 		} else
813 			idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
814 	}
815 	if (idx < 0 || idx >= bmachine.reg_array_size) {
816 		warnx("internal error: reg num = %d", idx);
817 		idx = -1;
818 	}
819 	return idx;
820 }
821 
822 static void
823 load(void)
824 {
825 	int		idx;
826 	struct value	*v, copy;
827 	struct number	*n;
828 
829 	idx = readreg();
830 	if (idx >= 0) {
831 		v = stack_tos(&bmachine.reg[idx]);
832 		if (v == NULL) {
833 			n = new_number();
834 			bn_check(BN_set_word(n->number, 0));
835 			push_number(n);
836 		} else
837 			push(stack_dup_value(v, &copy));
838 	}
839 }
840 
841 static void
842 store(void)
843 {
844 	int		idx;
845 	struct value	*val;
846 
847 	idx = readreg();
848 	if (idx >= 0) {
849 		val = pop();
850 		if (val == NULL) {
851 			return;
852 		}
853 		stack_set_tos(&bmachine.reg[idx], val);
854 	}
855 }
856 
857 static void
858 load_stack(void)
859 {
860 	int		idx;
861 	struct stack	*stack;
862 	struct value	*value;
863 
864 	idx = readreg();
865 	if (idx >= 0) {
866 		stack = &bmachine.reg[idx];
867 		value = NULL;
868 		if (stack_size(stack) > 0) {
869 			value = stack_pop(stack);
870 		}
871 		if (value != NULL)
872 			push(value);
873 		else
874 			warnx("stack register '%c' (0%o) is empty",
875 			    idx, idx);
876 	}
877 }
878 
879 static void
880 store_stack(void)
881 {
882 	int		idx;
883 	struct value	*value;
884 
885 	idx = readreg();
886 	if (idx >= 0) {
887 		value = pop();
888 		if (value == NULL)
889 			return;
890 		stack_push(&bmachine.reg[idx], value);
891 	}
892 }
893 
894 static void
895 load_array(void)
896 {
897 	int			reg;
898 	struct number		*inumber, *n;
899 	u_long			idx;
900 	struct stack		*stack;
901 	struct value		*v, copy;
902 
903 	reg = readreg();
904 	if (reg >= 0) {
905 		inumber = pop_number();
906 		if (inumber == NULL)
907 			return;
908 		idx = get_ulong(inumber);
909 		if (BN_is_negative(inumber->number))
910 			warnx("negative idx");
911 		else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
912 			warnx("idx too big");
913 		else {
914 			stack = &bmachine.reg[reg];
915 			v = frame_retrieve(stack, idx);
916 			if (v == NULL || v->type == BCODE_NONE) {
917 				n = new_number();
918 				bn_check(BN_set_word(n->number, 0));
919 				push_number(n);
920 			} else
921 				push(stack_dup_value(v, &copy));
922 		}
923 		free_number(inumber);
924 	}
925 }
926 
927 static void
928 store_array(void)
929 {
930 	int			reg;
931 	struct number		*inumber;
932 	u_long			idx;
933 	struct value		*value;
934 	struct stack		*stack;
935 
936 	reg = readreg();
937 	if (reg >= 0) {
938 		inumber = pop_number();
939 		if (inumber == NULL)
940 			return;
941 		value = pop();
942 		if (value == NULL) {
943 			free_number(inumber);
944 			return;
945 		}
946 		idx = get_ulong(inumber);
947 		if (BN_is_negative(inumber->number)) {
948 			warnx("negative idx");
949 			stack_free_value(value);
950 		} else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
951 			warnx("idx too big");
952 			stack_free_value(value);
953 		} else {
954 			stack = &bmachine.reg[reg];
955 			frame_assign(stack, idx, value);
956 		}
957 		free_number(inumber);
958 	}
959 }
960 
961 static void
962 push_line(void)
963 {
964 	push_string(read_string(&bmachine.readstack[bmachine.readsp]));
965 }
966 
967 static void
968 comment(void)
969 {
970 	free(readline());
971 }
972 
973 static void
974 badd(void)
975 {
976 	struct number	*a, *b;
977 
978 	a = pop_number();
979 	if (a == NULL)
980 		return;
981 	b = pop_number();
982 	if (b == NULL) {
983 		push_number(a);
984 		return;
985 	}
986 
987 	if (b->scale > a->scale)
988 		normalize(a, b->scale);
989 	else if (a->scale > b->scale)
990 		normalize(b, a->scale);
991 	bn_check(BN_add(b->number, a->number, b->number));
992 	free_number(a);
993 	push_number(b);
994 }
995 
996 static void
997 bsub(void)
998 {
999 	struct number	*a, *b;
1000 
1001 	a = pop_number();
1002 	if (a == NULL)
1003 		return;
1004 	b = pop_number();
1005 	if (b == NULL) {
1006 		push_number(a);
1007 		return;
1008 	}
1009 
1010 	if (b->scale > a->scale)
1011 		normalize(a, b->scale);
1012 	else if (a->scale > b->scale)
1013 		normalize(b, a->scale);
1014 	bn_check(BN_sub(b->number, b->number, a->number));
1015 	free_number(a);
1016 	push_number(b);
1017 }
1018 
1019 void
1020 bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
1021 {
1022 	/* Create copies of the scales, since r might be equal to a or b */
1023 	u_int ascale = a->scale;
1024 	u_int bscale = b->scale;
1025 	u_int rscale = ascale + bscale;
1026 
1027 	bn_check(BN_mul(r->number, a->number, b->number, bmachine.ctx));
1028 
1029 	r->scale = rscale;
1030 	if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1031 		normalize(r, max(scale, max(ascale, bscale)));
1032 }
1033 
1034 static void
1035 bmul(void)
1036 {
1037 	struct number	*a, *b;
1038 
1039 	a = pop_number();
1040 	if (a == NULL)
1041 		return;
1042 	b = pop_number();
1043 	if (b == NULL) {
1044 		push_number(a);
1045 		return;
1046 	}
1047 
1048 	bmul_number(b, a, b, bmachine.scale);
1049 	free_number(a);
1050 	push_number(b);
1051 }
1052 
1053 static void
1054 bdiv(void)
1055 {
1056 	struct number	*a, *b;
1057 	struct number	*r;
1058 	u_int		scale;
1059 
1060 	a = pop_number();
1061 	if (a == NULL)
1062 		return;
1063 	b = pop_number();
1064 	if (b == NULL) {
1065 		push_number(a);
1066 		return;
1067 	}
1068 
1069 	r = new_number();
1070 	r->scale = bmachine.scale;
1071 	scale = max(a->scale, b->scale);
1072 
1073 	if (BN_is_zero(a->number))
1074 		warnx("divide by zero");
1075 	else {
1076 		normalize(a, scale);
1077 		normalize(b, scale + r->scale);
1078 
1079 		bn_check(BN_div(r->number, NULL, b->number, a->number, bmachine.ctx));
1080 	}
1081 	push_number(r);
1082 	free_number(a);
1083 	free_number(b);
1084 }
1085 
1086 static void
1087 bmod(void)
1088 {
1089 	struct number	*a, *b;
1090 	struct number	*r;
1091 	u_int		scale;
1092 
1093 	a = pop_number();
1094 	if (a == NULL)
1095 		return;
1096 	b = pop_number();
1097 	if (b == NULL) {
1098 		push_number(a);
1099 		return;
1100 	}
1101 
1102 	r = new_number();
1103 	scale = max(a->scale, b->scale);
1104 	r->scale = max(b->scale, a->scale + bmachine.scale);
1105 
1106 	if (BN_is_zero(a->number))
1107 		warnx("remainder by zero");
1108 	else {
1109 		normalize(a, scale);
1110 		normalize(b, scale + bmachine.scale);
1111 
1112 		bn_check(BN_mod(r->number, b->number, a->number, bmachine.ctx));
1113 	}
1114 	push_number(r);
1115 	free_number(a);
1116 	free_number(b);
1117 }
1118 
1119 static void
1120 bdivmod(void)
1121 {
1122 	struct number	*a, *b;
1123 	struct number	*rdiv, *rmod;
1124 	u_int		scale;
1125 
1126 	a = pop_number();
1127 	if (a == NULL)
1128 		return;
1129 	b = pop_number();
1130 	if (b == NULL) {
1131 		push_number(a);
1132 		return;
1133 	}
1134 
1135 	rdiv = new_number();
1136 	rmod = new_number();
1137 	rdiv->scale = bmachine.scale;
1138 	rmod->scale = max(b->scale, a->scale + bmachine.scale);
1139 	scale = max(a->scale, b->scale);
1140 
1141 	if (BN_is_zero(a->number))
1142 		warnx("divide by zero");
1143 	else {
1144 		normalize(a, scale);
1145 		normalize(b, scale + bmachine.scale);
1146 
1147 		bn_check(BN_div(rdiv->number, rmod->number,
1148 		    b->number, a->number, bmachine.ctx));
1149 	}
1150 	push_number(rdiv);
1151 	push_number(rmod);
1152 	free_number(a);
1153 	free_number(b);
1154 }
1155 
1156 static void
1157 bexp(void)
1158 {
1159 	struct number	*a, *p;
1160 	struct number	*r;
1161 	bool		neg;
1162 	u_int		rscale;
1163 
1164 	p = pop_number();
1165 	if (p == NULL)
1166 		return;
1167 	a = pop_number();
1168 	if (a == NULL) {
1169 		push_number(p);
1170 		return;
1171 	}
1172 
1173 	if (p->scale != 0) {
1174 		BIGNUM *i, *f;
1175 		i = BN_new();
1176 		bn_checkp(i);
1177 		f = BN_new();
1178 		bn_checkp(f);
1179 		split_number(p, i, f);
1180 		if (!BN_is_zero(f))
1181 			warnx("Runtime warning: non-zero fractional part "
1182 			    "in exponent");
1183 		BN_free(p->number);
1184 		p->number = i;
1185 		BN_free(f);
1186 	}
1187 
1188 	neg = BN_is_negative(p->number);
1189 	if (neg) {
1190 		negate(p);
1191 		rscale = bmachine.scale;
1192 	} else {
1193 		/* Posix bc says min(a.scale * b, max(a.scale, scale)) */
1194 		u_long	b;
1195 		u_int	m;
1196 
1197 		b = BN_get_word(p->number);
1198 		m = max(a->scale, bmachine.scale);
1199 		rscale = a->scale * (u_int)b;
1200 		if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1201 		    b > UINT_MAX)))
1202 			rscale = m;
1203 	}
1204 
1205 	if (BN_is_zero(p->number)) {
1206 		r = new_number();
1207 		bn_check(BN_one(r->number));
1208 		normalize(r, rscale);
1209 	} else {
1210 		u_int ascale, mscale;
1211 
1212 		ascale = a->scale;
1213 		while (!BN_is_bit_set(p->number, 0)) {
1214 			ascale *= 2;
1215 			bmul_number(a, a, a, ascale);
1216 			bn_check(BN_rshift1(p->number, p->number));
1217 		}
1218 
1219 		r = dup_number(a);
1220 		bn_check(BN_rshift1(p->number, p->number));
1221 
1222 		mscale = ascale;
1223 		while (!BN_is_zero(p->number)) {
1224 			ascale *= 2;
1225 			bmul_number(a, a, a, ascale);
1226 			if (BN_is_bit_set(p->number, 0)) {
1227 				mscale += ascale;
1228 				bmul_number(r, r, a, mscale);
1229 			}
1230 			bn_check(BN_rshift1(p->number, p->number));
1231 		}
1232 
1233 		if (neg) {
1234 			BIGNUM	*one;
1235 
1236 			one = BN_new();
1237 			bn_checkp(one);
1238 			bn_check(BN_one(one));
1239 			scale_number(one, r->scale + rscale);
1240 
1241 			if (BN_is_zero(r->number))
1242 				warnx("divide by zero");
1243 			else
1244 				bn_check(BN_div(r->number, NULL, one,
1245 				    r->number, bmachine.ctx));
1246 			BN_free(one);
1247 			r->scale = rscale;
1248 		} else
1249 			normalize(r, rscale);
1250 	}
1251 	push_number(r);
1252 	free_number(a);
1253 	free_number(p);
1254 }
1255 
1256 static void
1257 bsqrt(void)
1258 {
1259 	struct number	*n;
1260 	struct number	*r;
1261 	BIGNUM		*x, *y, *t;
1262 	u_int		scale, onecount;
1263 
1264 	onecount = 0;
1265 	n = pop_number();
1266 	if (n == NULL)
1267 		return;
1268 	if (BN_is_zero(n->number)) {
1269 		r = new_number();
1270 		push_number(r);
1271 	} else if (BN_is_negative(n->number))
1272 		warnx("square root of negative number");
1273 	else {
1274 		scale = max(bmachine.scale, n->scale);
1275 		normalize(n, 2*scale);
1276 		x = BN_dup(n->number);
1277 		bn_checkp(x);
1278 		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1279 		y = BN_new();
1280 		bn_checkp(y);
1281 		do {
1282 			bn_check(BN_div(y, NULL, n->number, x, bmachine.ctx));
1283 			bn_check(BN_add(y, x, y));
1284 			bn_check(BN_rshift1(y, y));
1285 			bn_check(BN_sub(x, y, x));
1286 			t = x;
1287 			x = y;
1288 			y = t;
1289 		} while (!BN_is_zero(y) && (onecount += BN_is_one(y)) < 2);
1290 		bn_check(BN_sub(y, x, y));
1291 		r = bmalloc(sizeof(*r));
1292 		r->scale = scale;
1293 		r->number = y;
1294 		BN_free(x);
1295 		push_number(r);
1296 	}
1297 
1298 	free_number(n);
1299 }
1300 
1301 static void
1302 not(void)
1303 {
1304 	struct number	*a;
1305 
1306 	a = pop_number();
1307 	if (a == NULL)
1308 		return;
1309 	a->scale = 0;
1310 	bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1311 	push_number(a);
1312 }
1313 
1314 static void
1315 equal(void)
1316 {
1317 	compare(BCODE_EQUAL);
1318 }
1319 
1320 static void
1321 equal_numbers(void)
1322 {
1323 	struct number *a, *b, *r;
1324 
1325 	a = pop_number();
1326 	if (a == NULL)
1327 		return;
1328 	b = pop_number();
1329 	if (b == NULL) {
1330 		push_number(a);
1331 		return;
1332 	}
1333 	r = new_number();
1334 	bn_check(BN_set_word(r->number,
1335 	    compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1336 	push_number(r);
1337 }
1338 
1339 static void
1340 less_numbers(void)
1341 {
1342 	struct number *a, *b, *r;
1343 
1344 	a = pop_number();
1345 	if (a == NULL)
1346 		return;
1347 	b = pop_number();
1348 	if (b == NULL) {
1349 		push_number(a);
1350 		return;
1351 	}
1352 	r = new_number();
1353 	bn_check(BN_set_word(r->number,
1354 	    compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1355 	push_number(r);
1356 }
1357 
1358 static void
1359 lesseq_numbers(void)
1360 {
1361 	struct number *a, *b, *r;
1362 
1363 	a = pop_number();
1364 	if (a == NULL)
1365 		return;
1366 	b = pop_number();
1367 	if (b == NULL) {
1368 		push_number(a);
1369 		return;
1370 	}
1371 	r = new_number();
1372 	bn_check(BN_set_word(r->number,
1373 	    compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1374 	push_number(r);
1375 }
1376 
1377 static void
1378 less(void)
1379 {
1380 	compare(BCODE_LESS);
1381 }
1382 
1383 static void
1384 not_compare(void)
1385 {
1386 	switch (readch()) {
1387 	case '<':
1388 		compare(BCODE_NOT_LESS);
1389 		break;
1390 	case '>':
1391 		compare(BCODE_NOT_GREATER);
1392 		break;
1393 	case '=':
1394 		compare(BCODE_NOT_EQUAL);
1395 		break;
1396 	default:
1397 		unreadch();
1398 		warnx("! command is deprecated");
1399 		break;
1400 	}
1401 }
1402 
1403 static void
1404 greater(void)
1405 {
1406 	compare(BCODE_GREATER);
1407 }
1408 
1409 static bool
1410 compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1411 {
1412 	u_int	scale;
1413 	int	cmp;
1414 
1415 	scale = max(a->scale, b->scale);
1416 
1417 	if (scale > a->scale)
1418 		normalize(a, scale);
1419 	else if (scale > b->scale)
1420 		normalize(b, scale);
1421 
1422 	cmp = BN_cmp(a->number, b->number);
1423 
1424 	free_number(a);
1425 	free_number(b);
1426 
1427 	switch (type) {
1428 	case BCODE_EQUAL:
1429 		return cmp == 0;
1430 	case BCODE_NOT_EQUAL:
1431 		return cmp != 0;
1432 	case BCODE_LESS:
1433 		return cmp < 0;
1434 	case BCODE_NOT_LESS:
1435 		return cmp >= 0;
1436 	case BCODE_GREATER:
1437 		return cmp > 0;
1438 	case BCODE_NOT_GREATER:
1439 		return cmp <= 0;
1440 	}
1441 	return false;
1442 }
1443 
1444 static void
1445 compare(enum bcode_compare type)
1446 {
1447 	int		idx, elseidx;
1448 	struct number	*a, *b;
1449 	bool		ok;
1450 	struct value	*v;
1451 
1452 	elseidx = NO_ELSE;
1453 	idx = readreg();
1454 	if (readch() == 'e')
1455 		elseidx = readreg();
1456 	else
1457 		unreadch();
1458 
1459 	a = pop_number();
1460 	if (a == NULL)
1461 		return;
1462 	b = pop_number();
1463 	if (b == NULL) {
1464 		push_number(a);
1465 		return;
1466 	}
1467 
1468 	ok = compare_numbers(type, a, b);
1469 
1470 	if (!ok && elseidx != NO_ELSE)
1471 		idx = elseidx;
1472 
1473 	if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1474 		v = stack_tos(&bmachine.reg[idx]);
1475 		if (v == NULL)
1476 			warnx("register '%c' (0%o) is empty", idx, idx);
1477 		else {
1478 			switch(v->type) {
1479 			case BCODE_NONE:
1480 				warnx("register '%c' (0%o) is empty", idx, idx);
1481 				break;
1482 			case BCODE_NUMBER:
1483 				warn("eval called with non-string argument");
1484 				break;
1485 			case BCODE_STRING:
1486 				eval_string(bstrdup(v->u.string));
1487 				break;
1488 			}
1489 		}
1490 	}
1491 }
1492 
1493 static void
1494 nop(void)
1495 {
1496 }
1497 
1498 static void
1499 quit(void)
1500 {
1501 	if (bmachine.readsp < 2)
1502 		exit(0);
1503 	src_free();
1504 	bmachine.readsp--;
1505 	src_free();
1506 	bmachine.readsp--;
1507 }
1508 
1509 static void
1510 quitN(void)
1511 {
1512 	struct number	*n;
1513 	u_long		i;
1514 
1515 	n = pop_number();
1516 	if (n == NULL)
1517 		return;
1518 	i = get_ulong(n);
1519 	free_number(n);
1520 	if (i == BN_MASK2 || i == 0)
1521 		warnx("Q command requires a number >= 1");
1522 	else if (bmachine.readsp < i)
1523 		warnx("Q command argument exceeded string execution depth");
1524 	else {
1525 		while (i-- > 0) {
1526 			src_free();
1527 			bmachine.readsp--;
1528 		}
1529 	}
1530 }
1531 
1532 static void
1533 skipN(void)
1534 {
1535 	struct number	*n;
1536 	u_long		i;
1537 
1538 	n = pop_number();
1539 	if (n == NULL)
1540 		return;
1541 	i = get_ulong(n);
1542 	if (i == BN_MASK2)
1543 		warnx("J command requires a number >= 0");
1544 	else if (i > 0 && bmachine.readsp < i)
1545 		warnx("J command argument exceeded string execution depth");
1546 	else {
1547 		while (i-- > 0) {
1548 			src_free();
1549 			bmachine.readsp--;
1550 		}
1551 		skip_until_mark();
1552 	}
1553 }
1554 
1555 static void
1556 skip_until_mark(void)
1557 {
1558 	for (;;) {
1559 		switch (readch()) {
1560 		case 'M':
1561 			return;
1562 		case EOF:
1563 			errx(1, "mark not found");
1564 			return;
1565 		case 'l':
1566 		case 'L':
1567 		case 's':
1568 		case 'S':
1569 		case ':':
1570 		case ';':
1571 		case '<':
1572 		case '>':
1573 		case '=':
1574 			(void)readreg();
1575 			if (readch() == 'e')
1576 				(void)readreg();
1577 			else
1578 				unreadch();
1579 			break;
1580 		case '[':
1581 			free(read_string(&bmachine.readstack[bmachine.readsp]));
1582 			break;
1583 		case '!':
1584 			switch (readch()) {
1585 				case '<':
1586 				case '>':
1587 				case '=':
1588 					(void)readreg();
1589 					if (readch() == 'e')
1590 						(void)readreg();
1591 					else
1592 						unreadch();
1593 					break;
1594 				default:
1595 					free(readline());
1596 					break;
1597 			}
1598 			break;
1599 		default:
1600 			break;
1601 		}
1602 	}
1603 }
1604 
1605 static void
1606 parse_number(void)
1607 {
1608 	unreadch();
1609 	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1610 	    bmachine.ibase));
1611 }
1612 
1613 static void
1614 unknown(void)
1615 {
1616 	int ch = bmachine.readstack[bmachine.readsp].lastchar;
1617 	warnx("%c (0%o) is unimplemented", ch, ch);
1618 }
1619 
1620 static void
1621 eval_string(char *p)
1622 {
1623 	int ch;
1624 
1625 	if (bmachine.readsp > 0) {
1626 		/* Check for tail call. Do not recurse in that case. */
1627 		ch = readch();
1628 		if (ch == EOF) {
1629 			src_free();
1630 			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1631 			return;
1632 		} else
1633 			unreadch();
1634 	}
1635 	if (bmachine.readsp == bmachine.readstack_sz - 1) {
1636 		size_t newsz = bmachine.readstack_sz * 2;
1637 		struct source *stack;
1638 		stack = reallocarray(bmachine.readstack, newsz,
1639 		    sizeof(struct source));
1640 		if (stack == NULL)
1641 			err(1, "recursion too deep");
1642 		bmachine.readstack_sz = newsz;
1643 		bmachine.readstack = stack;
1644 	}
1645 	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1646 }
1647 
1648 static void
1649 eval_line(void)
1650 {
1651 	/* Always read from stdin */
1652 	struct source	in;
1653 	char		*p;
1654 
1655 	clearerr(stdin);
1656 	src_setstream(&in, stdin);
1657 	p = (*in.vtable->readline)(&in);
1658 	eval_string(p);
1659 }
1660 
1661 static void
1662 eval_tos(void)
1663 {
1664 	char *p;
1665 
1666 	p = pop_string();
1667 	if (p != NULL)
1668 		eval_string(p);
1669 }
1670 
1671 void
1672 eval(void)
1673 {
1674 	int	ch;
1675 
1676 	for (;;) {
1677 		ch = readch();
1678 		if (ch == EOF) {
1679 			if (bmachine.readsp == 0)
1680 				return;
1681 			src_free();
1682 			bmachine.readsp--;
1683 			continue;
1684 		}
1685 		if (bmachine.interrupted) {
1686 			if (bmachine.readsp > 0) {
1687 				src_free();
1688 				bmachine.readsp--;
1689 				continue;
1690 			} else
1691 				bmachine.interrupted = false;
1692 		}
1693 #ifdef DEBUGGING
1694 		(void)fprintf(stderr, "# %c\n", ch);
1695 		stack_print(stderr, &bmachine.stack, "* ",
1696 		    bmachine.obase);
1697 		(void)fprintf(stderr, "%zd =>\n", bmachine.readsp);
1698 #endif
1699 
1700 		if (0 <= ch && ch < nitems(jump_table))
1701 			(*jump_table[ch])();
1702 		else
1703 			unknown();
1704 
1705 #ifdef DEBUGGING
1706 		stack_print(stderr, &bmachine.stack, "* ",
1707 		    bmachine.obase);
1708 		(void)fprintf(stderr, "%zd ==\n", bmachine.readsp);
1709 #endif
1710 	}
1711 }
1712