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