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