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