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