GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/bc/../dc/bcode.c Lines: 442 758 58.3 %
Date: 2017-11-07 Branches: 147 329 44.7 %

Line Branch Exec Source
1
/*	$OpenBSD: bcode.c,v 1.51 2017/02/26 11:29:55 otto Exp $	*/
2
3
/*
4
 * Copyright (c) 2003, Otto Moerbeek <otto@drijf.net>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <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
2590
	bmachine.extended_regs = extended_registers;
233
2590
	bmachine.reg_array_size = bmachine.extended_regs ?
234
	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
235
236
2590
	bmachine.reg = calloc(bmachine.reg_array_size,
237
	    sizeof(bmachine.reg[0]));
238
2590
	if (bmachine.reg == NULL)
239
		err(1, NULL);
240
241
1326080
	for (i = 0; i < UCHAR_MAX; i++)
242
660450
		jump_table[i] = unknown;
243
378140
	for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
244
186480
		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
245
246
2590
	stack_init(&bmachine.stack);
247
248
340807740
	for (i = 0; i < bmachine.reg_array_size; i++)
249
170401280
		stack_init(&bmachine.reg[i]);
250
251
2590
	bmachine.readstack_sz = READSTACK_SIZE;
252
2590
	bmachine.readstack = calloc(sizeof(struct source),
253
	    bmachine.readstack_sz);
254
2590
	if (bmachine.readstack == NULL)
255
		err(1, NULL);
256
2590
	bmachine.obase = bmachine.ibase = 10;
257
2590
	(void)signal(SIGINT, sighandler);
258
2590
}
259
260
u_int
261
bmachine_scale(void)
262
{
263
53460
	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
5180
	bmachine.readsp = 0;
271
2590
	bmachine.readstack[0] = *src;
272
2590
}
273
274
static __inline int
275
readch(void)
276
{
277
5588870
	struct source *src = &bmachine.readstack[bmachine.readsp];
278
279
2794435
	return src->vtable->readchar(src);
280
}
281
282
static __inline void
283
unreadch(void)
284
{
285
556710
	struct source *src = &bmachine.readstack[bmachine.readsp];
286
287
278355
	src->vtable->unreadchar(src);
288
278355
}
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
77330
	struct source *src = &bmachine.readstack[bmachine.readsp];
302
303
38665
	src->vtable->free(src);
304
38665
}
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
453120
	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
369810
	if (s == 0)
348
36805
		return;
349
350
148100
	abs_scale = s > 0 ? s : -s;
351
352
148100
	if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
353
24315
		if (s > 0)
354
21520
			bn_check(BN_mul_word(n, factors[abs_scale]));
355
		else
356
2795
			(void)BN_div_word(n, factors[abs_scale]);
357
	} else {
358
		BIGNUM *a, *p;
359
		BN_CTX *ctx;
360
361
123785
		a = BN_new();
362
123785
		bn_checkp(a);
363
123785
		p = BN_new();
364
123785
		bn_checkp(p);
365
123785
		ctx = BN_CTX_new();
366
123785
		bn_checkp(ctx);
367
368
123785
		bn_check(BN_set_word(a, 10));
369
123785
		bn_check(BN_set_word(p, abs_scale));
370
123785
		bn_check(BN_exp(a, a, p, ctx));
371
123785
		if (s > 0)
372
100175
			bn_check(BN_mul(n, n, a, ctx));
373
		else
374
23610
			bn_check(BN_div(n, NULL, n, a, ctx));
375
123785
		BN_CTX_free(ctx);
376
123785
		BN_free(a);
377
123785
		BN_free(p);
378
	}
379
333005
}
380
381
void
382
split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
383
{
384
	u_long rem;
385
386
66390
	bn_checkp(BN_copy(i, n->number));
387
388
33195
	if (n->scale == 0 && f != NULL)
389
1785
		bn_check(BN_set_word(f, 0));
390
31410
	else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
391
4445
		rem = BN_div_word(i, factors[n->scale]);
392
4445
		if (f != NULL)
393
2465
			bn_check(BN_set_word(f, rem));
394
	} else {
395
		BIGNUM *a, *p;
396
		BN_CTX *ctx;
397
398
26965
		a = BN_new();
399
26965
		bn_checkp(a);
400
26965
		p = BN_new();
401
26965
		bn_checkp(p);
402
26965
		ctx = BN_CTX_new();
403
26965
		bn_checkp(ctx);
404
405
26965
		bn_check(BN_set_word(a, 10));
406
26965
		bn_check(BN_set_word(p, n->scale));
407
26965
		bn_check(BN_exp(a, a, p, ctx));
408
26965
		bn_check(BN_div(i, f, n->number, a, ctx));
409
26965
		BN_CTX_free(ctx);
410
26965
		BN_free(a);
411
26965
		BN_free(p);
412
	}
413
33195
}
414
415
void
416
normalize(struct number *n, u_int s)
417
{
418
365190
	scale_number(n->number, s - n->scale);
419
182595
	n->scale = s;
420
182595
}
421
422
static u_long
423
get_ulong(struct number *n)
424
{
425
58210
	normalize(n, 0);
426
29105
	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
837380
	stack_pushnumber(&bmachine.stack, n);
439
418690
}
440
441
static __inline void
442
push_string(char *string)
443
{
444
207200
	stack_pushstring(&bmachine.stack, string);
445
103600
}
446
447
static __inline void
448
push(struct value *v)
449
{
450
831040
	stack_push(&bmachine.stack, v);
451
415520
}
452
453
static __inline struct value *
454
tos(void)
455
{
456
5180
	return stack_tos(&bmachine.stack);
457
}
458
459
static __inline struct value *
460
pop(void)
461
{
462
801240
	return stack_pop(&bmachine.stack);
463
}
464
465
static __inline struct number *
466
pop_number(void)
467
{
468
1114730
	return stack_popnumber(&bmachine.stack);
469
}
470
471
static __inline char *
472
pop_string(void)
473
{
474
9380
	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
5180
	struct value *value = tos();
493
2590
	if (value != NULL) {
494
2590
		print_value(stdout, value, "", bmachine.obase);
495
5180
		(void)putchar('\n');
496
	}
497
	else
498
		warnx("stack empty");
499
2590
}
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
49730
	stack_dup(&bmachine.stack);
552
24865
}
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
14140
	n = new_number();
574
7070
	bn_check(BN_set_word(n->number, bmachine.scale));
575
7070
	push_number(n);
576
7070
}
577
578
static void
579
set_scale(void)
580
{
581
	struct number	*n;
582
	u_long		scale;
583
584
30210
	n = pop_number();
585
15105
	if (n != NULL) {
586
15105
		if (BN_is_negative(n->number))
587
			warnx("scale must be a nonnegative number");
588
		else {
589
15105
			scale = get_ulong(n);
590
15105
			if (scale != BN_MASK2 && scale <= UINT_MAX)
591
15105
				bmachine.scale = (u_int)scale;
592
			else
593
				warnx("scale too large");
594
			}
595
15105
		free_number(n);
596
15105
	}
597
15105
}
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
9310
	n = new_number();
632
4655
	bn_check(BN_set_word(n->number, bmachine.ibase));
633
4655
	push_number(n);
634
4655
}
635
636
static void
637
set_ibase(void)
638
{
639
	struct number	*n;
640
	u_long		base;
641
642
18620
	n = pop_number();
643
9310
	if (n != NULL) {
644
9310
		base = get_ulong(n);
645
9310
		if (base != BN_MASK2 && 2 <= base && base <= 16)
646
9310
			bmachine.ibase = (u_int)base;
647
		else
648
			warnx("input base must be a number between 2 and 16 "
649
			    "(inclusive)");
650
9310
		free_number(n);
651
9310
	}
652
9310
}
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
5180
	value = pop();
675
2590
	if (value != NULL) {
676
5180
		switch (value->type) {
677
		case BCODE_NONE:
678
			return;
679
		case BCODE_NUMBER:
680
2590
			scale = value->u.num->scale;
681
2590
			break;
682
		case BCODE_STRING:
683
			break;
684
		}
685
2590
		stack_free_value(value);
686
2590
		n = new_number();
687
2590
		bn_check(BN_set_word(n->number, scale));
688
2590
		push_number(n);
689
2590
	}
690
5180
}
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
7840
	if (BN_is_zero(n->number))
699
135
		return n->scale ? n->scale : 1;
700
701
3875
	int_part = new_number();
702
3875
	fract_part = new_number();
703
3875
	fract_part->scale = n->scale;
704
3875
	split_number(n, int_part->number, fract_part->number);
705
706
	i = 0;
707
17740
	while (!BN_is_zero(int_part->number)) {
708
4995
		(void)BN_div_word(int_part->number, 10);
709
4995
		i++;
710
	}
711
3875
	free_number(int_part);
712
3875
	free_number(fract_part);
713
3875
	return i + n->scale;
714
3920
}
715
716
static void
717
num_digits(void)
718
{
719
	struct value	*value;
720
	size_t		digits;
721
	struct number	*n = NULL;
722
723
7840
	value = pop();
724
3920
	if (value != NULL) {
725

7840
		switch (value->type) {
726
		case BCODE_NONE:
727
			return;
728
		case BCODE_NUMBER:
729
3920
			digits = count_digits(value->u.num);
730
3920
			n = new_number();
731
3920
			bn_check(BN_set_word(n->number, digits));
732
3920
			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
3920
		stack_free_value(value);
740
3920
		push_number(n);
741
3920
	}
742
7840
}
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
1748750
	idx = readch();
779

874375
	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

1748750
	if (idx < 0 || idx >= bmachine.reg_array_size) {
789
		warnx("internal error: reg num = %d", idx);
790
		idx = -1;
791
	}
792
874375
	return idx;
793
}
794
795
static void
796
load(void)
797
{
798
	int		idx;
799
735280
	struct value	*v, copy;
800
	struct number	*n;
801
802
367640
	idx = readreg();
803
367640
	if (idx >= 0) {
804
367640
		v = stack_tos(&bmachine.reg[idx]);
805
367640
		if (v == NULL) {
806
			n = new_number();
807
			bn_check(BN_set_word(n->number, 0));
808
			push_number(n);
809
		} else
810
367640
			push(stack_dup_value(v, &copy));
811
	}
812
367640
}
813
814
static void
815
store(void)
816
{
817
	int		idx;
818
	struct value	*val;
819
820
692460
	idx = readreg();
821
346230
	if (idx >= 0) {
822
346230
		val = pop();
823
346230
		if (val == NULL) {
824
			return;
825
		}
826
346230
		stack_set_tos(&bmachine.reg[idx], val);
827
346230
	}
828
692460
}
829
830
static void
831
load_stack(void)
832
{
833
	int		idx;
834
	struct stack	*stack;
835
	struct value	*value;
836
837
95760
	idx = readreg();
838
47880
	if (idx >= 0) {
839
47880
		stack = &bmachine.reg[idx];
840
		value = NULL;
841
47880
		if (stack_size(stack) > 0) {
842
47880
			value = stack_pop(stack);
843
47880
		}
844
47880
		if (value != NULL)
845
47880
			push(value);
846
		else
847
			warnx("stack register '%c' (0%o) is empty",
848
			    idx, idx);
849
	}
850
47880
}
851
852
static void
853
store_stack(void)
854
{
855
	int		idx;
856
	struct value	*value;
857
858
95760
	idx = readreg();
859
47880
	if (idx >= 0) {
860
47880
		value = pop();
861
47880
		if (value == NULL)
862
			return;
863
47880
		stack_push(&bmachine.reg[idx], value);
864
47880
	}
865
95760
}
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
207200
	push_string(read_string(&bmachine.readstack[bmachine.readsp]));
939
103600
}
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
108910
	a = pop_number();
954
54455
	if (a == NULL)
955
		return;
956
54455
	b = pop_number();
957
54455
	if (b == NULL) {
958
		push_number(a);
959
		return;
960
	}
961
962
54455
	r = new_number();
963
54455
	r->scale = max(a->scale, b->scale);
964
54455
	if (r->scale > a->scale)
965
3350
		normalize(a, r->scale);
966
51105
	else if (r->scale > b->scale)
967
2280
		normalize(b, r->scale);
968
54455
	bn_check(BN_add(r->number, a->number, b->number));
969
54455
	push_number(r);
970
54455
	free_number(a);
971
54455
	free_number(b);
972
108910
}
973
974
static void
975
bsub(void)
976
{
977
	struct number	*a, *b;
978
	struct number	*r;
979
980
34730
	a = pop_number();
981
17365
	if (a == NULL)
982
		return;
983
17365
	b = pop_number();
984
17365
	if (b == NULL) {
985
		push_number(a);
986
		return;
987
	}
988
989
17365
	r = new_number();
990
991
17365
	r->scale = max(a->scale, b->scale);
992
17365
	if (r->scale > a->scale)
993
995
		normalize(a, r->scale);
994
16370
	else if (r->scale > b->scale)
995
5765
		normalize(b, r->scale);
996
17365
	bn_check(BN_sub(r->number, b->number, a->number));
997
17365
	push_number(r);
998
17365
	free_number(a);
999
17365
	free_number(b);
1000
34730
}
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
238910
	u_int ascale = a->scale;
1009
119455
	u_int bscale = b->scale;
1010
119455
	u_int rscale = ascale + bscale;
1011
1012
119455
	ctx = BN_CTX_new();
1013
119455
	bn_checkp(ctx);
1014
119455
	bn_check(BN_mul(r->number, a->number, b->number, ctx));
1015
119455
	BN_CTX_free(ctx);
1016
1017
119455
	r->scale = rscale;
1018

193615
	if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1019
26405
		normalize(r, max(scale, max(ascale, bscale)));
1020
119455
}
1021
1022
static void
1023
bmul(void)
1024
{
1025
	struct number	*a, *b;
1026
	struct number	*r;
1027
1028
183700
	a = pop_number();
1029
91850
	if (a == NULL)
1030
		return;
1031
91850
	b = pop_number();
1032
91850
	if (b == NULL) {
1033
		push_number(a);
1034
		return;
1035
	}
1036
1037
91850
	r = new_number();
1038
91850
	bmul_number(r, a, b, bmachine.scale);
1039
1040
91850
	push_number(r);
1041
91850
	free_number(a);
1042
91850
	free_number(b);
1043
183700
}
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
68490
	a = pop_number();
1054
34245
	if (a == NULL)
1055
		return;
1056
34245
	b = pop_number();
1057
34245
	if (b == NULL) {
1058
		push_number(a);
1059
		return;
1060
	}
1061
1062
34245
	r = new_number();
1063
34245
	r->scale = bmachine.scale;
1064
34245
	scale = max(a->scale, b->scale);
1065
1066
34245
	if (BN_is_zero(a->number))
1067
		warnx("divide by zero");
1068
	else {
1069
34245
		normalize(a, scale);
1070
34245
		normalize(b, scale + r->scale);
1071
1072
34245
		ctx = BN_CTX_new();
1073
34245
		bn_checkp(ctx);
1074
34245
		bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1075
34245
		BN_CTX_free(ctx);
1076
	}
1077
34245
	push_number(r);
1078
34245
	free_number(a);
1079
34245
	free_number(b);
1080
68490
}
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
2100
	a = pop_number();
1091
1050
	if (a == NULL)
1092
		return;
1093
1050
	b = pop_number();
1094
1050
	if (b == NULL) {
1095
		push_number(a);
1096
		return;
1097
	}
1098
1099
1050
	r = new_number();
1100
1050
	scale = max(a->scale, b->scale);
1101
1050
	r->scale = max(b->scale, a->scale + bmachine.scale);
1102
1103
1050
	if (BN_is_zero(a->number))
1104
		warnx("remainder by zero");
1105
	else {
1106
1050
		normalize(a, scale);
1107
1050
		normalize(b, scale + bmachine.scale);
1108
1109
1050
		ctx = BN_CTX_new();
1110
1050
		bn_checkp(ctx);
1111
1050
		bn_check(BN_mod(r->number, b->number, a->number, ctx));
1112
1050
		BN_CTX_free(ctx);
1113
	}
1114
1050
	push_number(r);
1115
1050
	free_number(a);
1116
1050
	free_number(b);
1117
2100
}
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
490
	p = pop_number();
1169
245
	if (p == NULL)
1170
		return;
1171
245
	a = pop_number();
1172
245
	if (a == NULL) {
1173
		push_number(p);
1174
		return;
1175
	}
1176
1177
245
	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
245
	normalize(p, 0);
1191
1192
	neg = false;
1193
245
	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
245
		b = BN_get_word(p->number);
1203
245
		m = max(a->scale, bmachine.scale);
1204
245
		rscale = a->scale * (u_int)b;
1205

490
		if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1206
		    b > UINT_MAX)))
1207
			rscale = m;
1208
	}
1209
1210
245
	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
245
		ascale = a->scale;
1218
840
		while (!BN_is_bit_set(p->number, 0)) {
1219
175
			ascale *= 2;
1220
175
			bmul_number(a, a, a, ascale);
1221
175
			bn_check(BN_rshift1(p->number, p->number));
1222
		}
1223
1224
245
		r = dup_number(a);
1225
245
		bn_check(BN_rshift1(p->number, p->number));
1226
1227
		mscale = ascale;
1228
1260
		while (!BN_is_zero(p->number)) {
1229
385
			ascale *= 2;
1230
385
			bmul_number(a, a, a, ascale);
1231
385
			if (BN_is_bit_set(p->number, 0)) {
1232
315
				mscale += ascale;
1233
315
				bmul_number(r, r, a, mscale);
1234
315
			}
1235
385
			bn_check(BN_rshift1(p->number, p->number));
1236
		}
1237
1238
245
		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
245
			normalize(r, rscale);
1259
	}
1260
245
	push_number(r);
1261
245
	free_number(a);
1262
245
	free_number(p);
1263
490
}
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
9490
	r = BN_new();
1272
4745
	bn_checkp(r);
1273
4745
	bn_check(BN_sub(r, x, y));
1274

7825
	if (BN_is_one(r))
1275
		(*onecount)++;
1276
4745
	ret = BN_is_zero(r);
1277
4745
	BN_free(r);
1278
13395
	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
1680
	u_int		scale, onecount;
1288
	BN_CTX		*ctx;
1289
1290
840
	onecount = 0;
1291
840
	n = pop_number();
1292
840
	if (n == NULL)
1293
		return;
1294
840
	if (BN_is_zero(n->number)) {
1295
		r = new_number();
1296
		push_number(r);
1297
840
	} else if (BN_is_negative(n->number))
1298
		warnx("square root of negative number");
1299
	else {
1300
840
		scale = max(bmachine.scale, n->scale);
1301
840
		normalize(n, 2*scale);
1302
840
		x = BN_dup(n->number);
1303
840
		bn_checkp(x);
1304
840
		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1305
840
		y = BN_new();
1306
840
		bn_checkp(y);
1307
840
		ctx = BN_CTX_new();
1308
840
		bn_checkp(ctx);
1309
840
		for (;;) {
1310
4745
			bn_checkp(BN_copy(y, x));
1311
4745
			bn_check(BN_div(x, NULL, n->number, x, ctx));
1312
4745
			bn_check(BN_add(x, x, y));
1313
4745
			bn_check(BN_rshift1(x, x));
1314
4745
			if (bsqrt_stop(x, y, &onecount))
1315
				break;
1316
		}
1317
840
		r = bmalloc(sizeof(*r));
1318
840
		r->scale = scale;
1319
840
		r->number = y;
1320
840
		BN_free(x);
1321
840
		BN_CTX_free(ctx);
1322
840
		push_number(r);
1323
	}
1324
1325
840
	free_number(n);
1326
1680
}
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
105340
	compare(BCODE_EQUAL);
1345
52670
}
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
3850
	compare(BCODE_NOT_EQUAL);
1408
1925
}
1409
1410
static void
1411
less(void)
1412
{
1413
5040
	compare(BCODE_LESS);
1414
2520
}
1415
1416
static void
1417
not_compare(void)
1418
{
1419

6930
	switch (readch()) {
1420
	case '<':
1421
490
		not_less();
1422
490
		break;
1423
	case '>':
1424
1050
		not_greater();
1425
1050
		break;
1426
	case '=':
1427
1925
		not_equal();
1428
1925
		break;
1429
	default:
1430
		unreadch();
1431
		(void)fprintf(stderr, "! command is deprecated\n");
1432
		break;
1433
	}
1434
3465
}
1435
1436
static void
1437
not_less(void)
1438
{
1439
980
	compare(BCODE_NOT_LESS);
1440
490
}
1441
1442
static void
1443
greater(void)
1444
{
1445
11690
	compare(BCODE_GREATER);
1446
5845
}
1447
1448
static void
1449
not_greater(void)
1450
{
1451
2100
	compare(BCODE_NOT_GREATER);
1452
1050
}
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
129000
	scale = max(a->scale, b->scale);
1461
1462
64500
	if (scale > a->scale)
1463
16045
		normalize(a, scale);
1464
48455
	else if (scale > b->scale)
1465
		normalize(b, scale);
1466
1467
64500
	cmp = BN_cmp(a->number, b->number);
1468
1469
64500
	free_number(a);
1470
64500
	free_number(b);
1471
1472

64500
	switch (type) {
1473
	case BCODE_EQUAL:
1474
52670
		return cmp == 0;
1475
	case BCODE_NOT_EQUAL:
1476
1925
		return cmp != 0;
1477
	case BCODE_LESS:
1478
2520
		return cmp < 0;
1479
	case BCODE_NOT_LESS:
1480
490
		return cmp >= 0;
1481
	case BCODE_GREATER:
1482
5845
		return cmp > 0;
1483
	case BCODE_NOT_GREATER:
1484
1050
		return cmp <= 0;
1485
	}
1486
	return false;
1487
64500
}
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
129000
	idx = readreg();
1499
64500
	if (readch() == 'e')
1500
245
		elseidx = readreg();
1501
	else
1502
64255
		unreadch();
1503
1504
64500
	a = pop_number();
1505
64500
	if (a == NULL)
1506
		return;
1507
64500
	b = pop_number();
1508
64500
	if (b == NULL) {
1509
		push_number(a);
1510
		return;
1511
	}
1512
1513
64500
	ok = compare_numbers(type, a, b);
1514
1515
64500
	if (!ok && elseidx != NO_ELSE)
1516
175
		idx = elseidx;
1517
1518

159700
	if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1519
33975
		v = stack_tos(&bmachine.reg[idx]);
1520
33975
		if (v == NULL)
1521
			warnx("register '%c' (0%o) is empty", idx, idx);
1522
		else {
1523

94905
			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
33975
				eval_string(bstrdup(v->u.string));
1532
33975
				break;
1533
			}
1534
		}
1535
	}
1536
129000
}
1537
1538
1539
static void
1540
nop(void)
1541
{
1542
704920
}
1543
1544
static void
1545
quit(void)
1546
{
1547
5180
	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
9380
	n = pop_number();
1562
4690
	if (n == NULL)
1563
		return;
1564
4690
	i = get_ulong(n);
1565
4690
	free_number(n);
1566
4690
	if (i == BN_MASK2 || i == 0)
1567
		warnx("Q command requires a number >= 1");
1568
4690
	else if (bmachine.readsp < i)
1569
		warnx("Q command argument exceeded string execution depth");
1570
	else {
1571
30660
		while (i-- > 0) {
1572
12985
			src_free();
1573
12985
			bmachine.readsp--;
1574
		}
1575
	}
1576
9380
}
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
400810
	unreadch();
1658
400810
	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1659
200405
	    bmachine.ibase));
1660
200405
}
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
77330
	if (bmachine.readsp > 0) {
1675
		/* Check for tail call. Do not recurse in that case. */
1676
36075
		ch = readch();
1677
36075
		if (ch == EOF) {
1678
22380
			src_free();
1679
22380
			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1680
22380
			return;
1681
		} else
1682
13695
			unreadch();
1683
13695
	}
1684
16285
	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
16285
	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1695
54950
}
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
9380
	p = pop_string();
1716
4690
	if (p != NULL)
1717
4690
		eval_string(p);
1718
4690
}
1719
1720
void
1721
eval(void)
1722
{
1723
	int	ch;
1724
1725
5180
	for (;;) {
1726
1816020
		ch = readch();
1727
1816020
		if (ch == EOF) {
1728
3300
			if (bmachine.readsp == 0)
1729
				return;
1730
3300
			src_free();
1731
3300
			bmachine.readsp--;
1732
3300
			continue;
1733
		}
1734
1812720
		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
1812720
		if (0 <= ch && ch < UCHAR_MAX)
1750
1812720
			(*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
}