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