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