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