GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/dc/bcode.c Lines: 671 795 84.4 %
Date: 2016-12-06 Branches: 212 321 66.0 %

Line Branch Exec Source
1
/*	$OpenBSD: bcode.c,v 1.49 2016/03/27 15:55:13 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		pop_print(void);
71
static void		pop_printn(void);
72
static __inline void	print_stack(void);
73
static __inline void	dup(void);
74
static void		swap(void);
75
static void		drop(void);
76
77
static void		get_scale(void);
78
static void		set_scale(void);
79
static void		get_obase(void);
80
static void		set_obase(void);
81
static void		get_ibase(void);
82
static void		set_ibase(void);
83
static void		stackdepth(void);
84
static void		push_scale(void);
85
static u_int		count_digits(const struct number *);
86
static void		num_digits(void);
87
static void		to_ascii(void);
88
static void		push_line(void);
89
static void		comment(void);
90
static void		badd(void);
91
static void		bsub(void);
92
static void		bmul(void);
93
static void		bdiv(void);
94
static void		bmod(void);
95
static void		bdivmod(void);
96
static void		bexp(void);
97
static bool		bsqrt_stop(const BIGNUM *, const BIGNUM *, u_int *);
98
static void		bsqrt(void);
99
static void		not(void);
100
static void		equal_numbers(void);
101
static void		less_numbers(void);
102
static void		lesseq_numbers(void);
103
static void		equal(void);
104
static void		not_equal(void);
105
static void		less(void);
106
static void		not_less(void);
107
static void		greater(void);
108
static void		not_greater(void);
109
static void		not_compare(void);
110
static bool		compare_numbers(enum bcode_compare, struct number *,
111
			    struct number *);
112
static void		compare(enum bcode_compare);
113
static int		readreg(void);
114
static void		load(void);
115
static void		store(void);
116
static void		load_stack(void);
117
static void		store_stack(void);
118
static void		load_array(void);
119
static void		store_array(void);
120
static void		nop(void);
121
static void		quit(void);
122
static void		quitN(void);
123
static void		skipN(void);
124
static void		skip_until_mark(void);
125
static void		parse_number(void);
126
static void		unknown(void);
127
static void		eval_string(char *);
128
static void		eval_line(void);
129
static void		eval_tos(void);
130
131
132
typedef void		(*opcode_function)(void);
133
134
struct jump_entry {
135
	u_char		ch;
136
	opcode_function	f;
137
};
138
139
static opcode_function jump_table[UCHAR_MAX];
140
141
static const struct jump_entry jump_table_data[] = {
142
	{ ' ',	nop		},
143
	{ '!',	not_compare	},
144
	{ '#',	comment		},
145
	{ '%',	bmod		},
146
	{ '(',	less_numbers	},
147
	{ '*',	bmul		},
148
	{ '+',	badd		},
149
	{ '-',	bsub		},
150
	{ '.',	parse_number	},
151
	{ '/',	bdiv		},
152
	{ '0',	parse_number	},
153
	{ '1',	parse_number	},
154
	{ '2',	parse_number	},
155
	{ '3',	parse_number	},
156
	{ '4',	parse_number	},
157
	{ '5',	parse_number	},
158
	{ '6',	parse_number	},
159
	{ '7',	parse_number	},
160
	{ '8',	parse_number	},
161
	{ '9',	parse_number	},
162
	{ ':',	store_array	},
163
	{ ';',	load_array	},
164
	{ '<',	less		},
165
	{ '=',	equal		},
166
	{ '>',	greater		},
167
	{ '?',	eval_line	},
168
	{ 'A',	parse_number	},
169
	{ 'B',	parse_number	},
170
	{ 'C',	parse_number	},
171
	{ 'D',	parse_number	},
172
	{ 'E',	parse_number	},
173
	{ 'F',	parse_number	},
174
	{ 'G',	equal_numbers	},
175
	{ 'I',	get_ibase	},
176
	{ 'J',	skipN		},
177
	{ 'K',	get_scale	},
178
	{ 'L',	load_stack	},
179
	{ 'M',	nop		},
180
	{ 'N',	not		},
181
	{ 'O',	get_obase	},
182
	{ 'P',	pop_print	},
183
	{ 'Q',	quitN		},
184
	{ 'R',	drop		},
185
	{ 'S',	store_stack	},
186
	{ 'X',	push_scale	},
187
	{ 'Z',	num_digits	},
188
	{ '[',	push_line	},
189
	{ '\f',	nop		},
190
	{ '\n',	nop		},
191
	{ '\r',	nop		},
192
	{ '\t',	nop		},
193
	{ '^',	bexp		},
194
	{ '_',	parse_number	},
195
	{ 'a',	to_ascii	},
196
	{ 'c',	clear_stack	},
197
	{ 'd',	dup		},
198
	{ 'f',	print_stack	},
199
	{ 'i',	set_ibase	},
200
	{ 'k',	set_scale	},
201
	{ 'l',	load		},
202
	{ 'n',	pop_printn	},
203
	{ 'o',	set_obase	},
204
	{ 'p',	print_tos	},
205
	{ 'q',	quit		},
206
	{ 'r',	swap		},
207
	{ 's',	store		},
208
	{ 'v',	bsqrt		},
209
	{ 'x',	eval_tos	},
210
	{ 'z',	stackdepth	},
211
	{ '{',	lesseq_numbers	},
212
	{ '~',	bdivmod		}
213
};
214
215
#define JUMP_TABLE_DATA_SIZE \
216
	(sizeof(jump_table_data)/sizeof(jump_table_data[0]))
217
218
/* ARGSUSED */
219
static void
220
sighandler(int ignored)
221
{
222
	bmachine.interrupted = true;
223
}
224
225
void
226
init_bmachine(bool extended_registers)
227
27
{
228
	int i;
229
230
27
	bmachine.extended_regs = extended_registers;
231
27
	bmachine.reg_array_size = bmachine.extended_regs ?
232
	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
233
234
27
	bmachine.reg = calloc(bmachine.reg_array_size,
235
	    sizeof(bmachine.reg[0]));
236
27
	if (bmachine.reg == NULL)
237
		err(1, NULL);
238
239
6912
	for (i = 0; i < UCHAR_MAX; i++)
240
6885
		jump_table[i] = unknown;
241
1944
	for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
242
1917
		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
243
244
27
	stack_init(&bmachine.stack);
245
246
1776411
	for (i = 0; i < bmachine.reg_array_size; i++)
247
1776384
		stack_init(&bmachine.reg[i]);
248
249
27
	bmachine.readstack_sz = READSTACK_SIZE;
250
27
	bmachine.readstack = calloc(sizeof(struct source),
251
	    bmachine.readstack_sz);
252
27
	if (bmachine.readstack == NULL)
253
		err(1, NULL);
254
27
	bmachine.obase = bmachine.ibase = 10;
255
27
	(void)signal(SIGINT, sighandler);
256
27
}
257
258
u_int
259
bmachine_scale(void)
260
4902
{
261
4902
	return bmachine.scale;
262
}
263
264
/* Reset the things needed before processing a (new) file */
265
void
266
reset_bmachine(struct source *src)
267
27
{
268
27
	bmachine.readsp = 0;
269
27
	bmachine.readstack[0] = *src;
270
27
}
271
272
static __inline int
273
readch(void)
274
184019
{
275
184019
	struct source *src = &bmachine.readstack[bmachine.readsp];
276
277
184019
	return src->vtable->readchar(src);
278
}
279
280
static __inline void
281
unreadch(void)
282
27359
{
283
27359
	struct source *src = &bmachine.readstack[bmachine.readsp];
284
285
27359
	src->vtable->unreadchar(src);
286
27359
}
287
288
static __inline char *
289
readline(void)
290
1335
{
291
1335
	struct source *src = &bmachine.readstack[bmachine.readsp];
292
293
1335
	return src->vtable->readline(src);
294
}
295
296
static __inline void
297
src_free(void)
298
5223
{
299
5223
	struct source *src = &bmachine.readstack[bmachine.readsp];
300
301
5223
	src->vtable->free(src);
302
5223
}
303
304
#ifdef DEBUGGING
305
void
306
pn(const char *str, const struct number *n)
307
{
308
	char *p = BN_bn2dec(n->number);
309
	if (p == NULL)
310
		err(1, "BN_bn2dec failed");
311
	(void)fputs(str, stderr);
312
	(void)fprintf(stderr, " %s (%u)\n" , p, n->scale);
313
	OPENSSL_free(p);
314
}
315
316
void
317
pbn(const char *str, const BIGNUM *n)
318
{
319
	char *p = BN_bn2dec(n);
320
	if (p == NULL)
321
		err(1, "BN_bn2dec failed");
322
	(void)fputs(str, stderr);
323
	(void)fprintf(stderr, " %s\n", p);
324
	OPENSSL_free(p);
325
}
326
327
#endif
328
329
static __inline u_int
330
max(u_int a, u_int b)
331
14983
{
332
21447
	return a > b ? a : b;
333
}
334
335
static unsigned long factors[] = {
336
	0, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
337
	100000000, 1000000000
338
};
339
340
void
341
scale_number(BIGNUM *n, int s)
342
25239
{
343
	int abs_scale;
344
345
25239
	if (s == 0)
346
13988
		return;
347
348
11251
	abs_scale = s > 0 ? s : -s;
349
350
11251
	if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
351
8428
		if (s > 0)
352
8424
			bn_check(BN_mul_word(n, factors[abs_scale]));
353
		else
354
4
			(void)BN_div_word(n, factors[abs_scale]);
355
	} else {
356
		BIGNUM *a, *p;
357
		BN_CTX *ctx;
358
359
2823
		a = BN_new();
360
2823
		bn_checkp(a);
361
2823
		p = BN_new();
362
2823
		bn_checkp(p);
363
2823
		ctx = BN_CTX_new();
364
2823
		bn_checkp(ctx);
365
366
2823
		bn_check(BN_set_word(a, 10));
367
2823
		bn_check(BN_set_word(p, abs_scale));
368
2823
		bn_check(BN_exp(a, a, p, ctx));
369
2823
		if (s > 0)
370
2107
			bn_check(BN_mul(n, n, a, ctx));
371
		else
372
716
			bn_check(BN_div(n, NULL, n, a, ctx));
373
2823
		BN_CTX_free(ctx);
374
2823
		BN_free(a);
375
2823
		BN_free(p);
376
	}
377
}
378
379
void
380
split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
381
10329
{
382
	u_long rem;
383
384
10329
	bn_checkp(BN_copy(i, n->number));
385
386
10329
	if (n->scale == 0 && f != NULL)
387
3306
		bn_check(BN_zero(f));
388
7023
	else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
389
6381
		rem = BN_div_word(i, factors[n->scale]);
390
6381
		if (f != NULL)
391
2113
			bn_check(BN_set_word(f, rem));
392
	} else {
393
		BIGNUM *a, *p;
394
		BN_CTX *ctx;
395
396
642
		a = BN_new();
397
642
		bn_checkp(a);
398
642
		p = BN_new();
399
642
		bn_checkp(p);
400
642
		ctx = BN_CTX_new();
401
642
		bn_checkp(ctx);
402
403
642
		bn_check(BN_set_word(a, 10));
404
642
		bn_check(BN_set_word(p, n->scale));
405
642
		bn_check(BN_exp(a, a, p, ctx));
406
642
		bn_check(BN_div(i, f, n->number, a, ctx));
407
642
		BN_CTX_free(ctx);
408
642
		BN_free(a);
409
642
		BN_free(p);
410
	}
411
10329
}
412
413
void
414
normalize(struct number *n, u_int s)
415
23036
{
416
23036
	scale_number(n->number, s - n->scale);
417
23036
	n->scale = s;
418
23036
}
419
420
static u_long
421
get_ulong(struct number *n)
422
1690
{
423
1690
	normalize(n, 0);
424
1690
	return BN_get_word(n->number);
425
}
426
427
void
428
negate(struct number *n)
429
46
{
430
46
	BN_set_negative(n->number, !BN_is_negative(n->number));
431
46
}
432
433
static __inline void
434
push_number(struct number *n)
435
37810
{
436
37810
	stack_pushnumber(&bmachine.stack, n);
437
37810
}
438
439
static __inline void
440
push_string(char *string)
441
756
{
442
756
	stack_pushstring(&bmachine.stack, string);
443
756
}
444
445
static __inline void
446
push(struct value *v)
447
20629
{
448
20629
	stack_push(&bmachine.stack, v);
449
20629
}
450
451
static __inline struct value *
452
tos(void)
453
5045
{
454
5045
	return stack_tos(&bmachine.stack);
455
}
456
457
static __inline struct value *
458
pop(void)
459
17904
{
460
17904
	return stack_pop(&bmachine.stack);
461
}
462
463
static __inline struct number *
464
pop_number(void)
465
33802
{
466
45210
	return stack_popnumber(&bmachine.stack);
467
}
468
469
static __inline char *
470
pop_string(void)
471
2273
{
472
2273
	return stack_popstring(&bmachine.stack);
473
}
474
475
static __inline void
476
clear_stack(void)
477
3
{
478
3
	stack_clear(&bmachine.stack);
479
3
}
480
481
static __inline void
482
print_stack(void)
483
8
{
484
8
	stack_print(stdout, &bmachine.stack, "", bmachine.obase);
485
8
}
486
487
static __inline void
488
print_tos(void)
489
5045
{
490
5045
	struct value *value = tos();
491
5045
	if (value != NULL) {
492
5045
		print_value(stdout, value, "", bmachine.obase);
493
5045
		(void)putchar('\n');
494
	}
495
	else
496
		warnx("stack empty");
497
5045
}
498
499
static void
500
pop_print(void)
501
3356
{
502
3356
	struct value *value = pop();
503
504
3356
	if (value != NULL) {
505
3356
		switch (value->type) {
506
		case BCODE_NONE:
507
			break;
508
		case BCODE_NUMBER:
509
1975
			normalize(value->u.num, 0);
510
1975
			print_ascii(stdout, value->u.num);
511
1975
			(void)fflush(stdout);
512
1975
			break;
513
		case BCODE_STRING:
514
1381
			(void)fputs(value->u.string, stdout);
515
1381
			(void)fflush(stdout);
516
			break;
517
		}
518
3356
		stack_free_value(value);
519
	}
520
3356
}
521
522
static void
523
pop_printn(void)
524
179
{
525
179
	struct value *value = pop();
526
527
179
	if (value != NULL) {
528
179
		print_value(stdout, value, "", bmachine.obase);
529
179
		(void)fflush(stdout);
530
179
		stack_free_value(value);
531
	}
532
179
}
533
534
static __inline void
535
dup(void)
536
6277
{
537
6277
	stack_dup(&bmachine.stack);
538
6277
}
539
540
static void
541
swap(void)
542
7
{
543
7
	stack_swap(&bmachine.stack);
544
7
}
545
546
static void
547
drop(void)
548
3
{
549
3
	struct value *v = pop();
550
3
	if (v != NULL)
551
3
		stack_free_value(v);
552
3
}
553
554
static void
555
get_scale(void)
556
5
{
557
	struct number	*n;
558
559
5
	n = new_number();
560
5
	bn_check(BN_set_word(n->number, bmachine.scale));
561
5
	push_number(n);
562
5
}
563
564
static void
565
set_scale(void)
566
13
{
567
	struct number	*n;
568
	u_long		scale;
569
570
13
	n = pop_number();
571
13
	if (n != NULL) {
572
13
		if (BN_is_negative(n->number))
573
			warnx("scale must be a nonnegative number");
574
		else {
575
13
			scale = get_ulong(n);
576
13
			if (scale != BN_MASK2 && scale <= UINT_MAX)
577
13
				bmachine.scale = (u_int)scale;
578
			else
579
				warnx("scale too large");
580
			}
581
13
		free_number(n);
582
	}
583
13
}
584
585
static void
586
get_obase(void)
587
{
588
	struct number	*n;
589
590
	n = new_number();
591
	bn_check(BN_set_word(n->number, bmachine.obase));
592
	push_number(n);
593
}
594
595
static void
596
set_obase(void)
597
629
{
598
	struct number	*n;
599
	u_long		base;
600
601
629
	n = pop_number();
602
629
	if (n != NULL) {
603
629
		base = get_ulong(n);
604
629
		if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
605
629
			bmachine.obase = (u_int)base;
606
		else
607
			warnx("output base must be a number greater than 1");
608
629
		free_number(n);
609
	}
610
629
}
611
612
static void
613
get_ibase(void)
614
{
615
	struct number *n;
616
617
	n = new_number();
618
	bn_check(BN_set_word(n->number, bmachine.ibase));
619
	push_number(n);
620
}
621
622
static void
623
set_ibase(void)
624
4
{
625
	struct number	*n;
626
	u_long		base;
627
628
4
	n = pop_number();
629
4
	if (n != NULL) {
630
4
		base = get_ulong(n);
631
4
		if (base != BN_MASK2 && 2 <= base && base <= 16)
632
4
			bmachine.ibase = (u_int)base;
633
		else
634
			warnx("input base must be a number between 2 and 16 "
635
			    "(inclusive)");
636
4
		free_number(n);
637
	}
638
4
}
639
640
static void
641
stackdepth(void)
642
2
{
643
	size_t i;
644
	struct number *n;
645
646
2
	i = stack_size(&bmachine.stack);
647
2
	n = new_number();
648
2
	bn_check(BN_set_word(n->number, i));
649
2
	push_number(n);
650
2
}
651
652
static void
653
push_scale(void)
654
7
{
655
	struct value	*value;
656
7
	u_int		scale = 0;
657
	struct number	*n;
658
659
660
7
	value = pop();
661
7
	if (value != NULL) {
662
7
		switch (value->type) {
663
		case BCODE_NONE:
664
			return;
665
		case BCODE_NUMBER:
666
5
			scale = value->u.num->scale;
667
			break;
668
		case BCODE_STRING:
669
			break;
670
		}
671
7
		stack_free_value(value);
672
7
		n = new_number();
673
7
		bn_check(BN_set_word(n->number, scale));
674
7
		push_number(n);
675
	}
676
}
677
678
static u_int
679
count_digits(const struct number *n)
680
326
{
681
	struct number	*int_part, *fract_part;
682
	u_int		i;
683
684
326
	if (BN_is_zero(n->number))
685
2
		return n->scale ? n->scale : 1;
686
687
324
	int_part = new_number();
688
324
	fract_part = new_number();
689
324
	fract_part->scale = n->scale;
690
324
	split_number(n, int_part->number, fract_part->number);
691
692
324
	i = 0;
693
1918
	while (!BN_is_zero(int_part->number)) {
694
1270
		(void)BN_div_word(int_part->number, 10);
695
1270
		i++;
696
	}
697
324
	free_number(int_part);
698
324
	free_number(fract_part);
699
324
	return i + n->scale;
700
}
701
702
static void
703
num_digits(void)
704
329
{
705
	struct value	*value;
706
	size_t		digits;
707
329
	struct number	*n = NULL;
708
709
329
	value = pop();
710
329
	if (value != NULL) {
711

329
		switch (value->type) {
712
		case BCODE_NONE:
713
			return;
714
		case BCODE_NUMBER:
715
326
			digits = count_digits(value->u.num);
716
326
			n = new_number();
717
326
			bn_check(BN_set_word(n->number, digits));
718
326
			break;
719
		case BCODE_STRING:
720
3
			digits = strlen(value->u.string);
721
3
			n = new_number();
722
3
			bn_check(BN_set_word(n->number, digits));
723
			break;
724
		}
725
329
		stack_free_value(value);
726
329
		push_number(n);
727
	}
728
}
729
730
static void
731
to_ascii(void)
732
103
{
733
	char		str[2];
734
	struct value	*value;
735
	struct number	*n;
736
737
103
	value = pop();
738
103
	if (value != NULL) {
739
103
		str[1] = '\0';
740

103
		switch (value->type) {
741
		case BCODE_NONE:
742
			return;
743
		case BCODE_NUMBER:
744
100
			n = value->u.num;
745
100
			normalize(n, 0);
746
100
			if (BN_num_bits(n->number) > 8)
747
1
				bn_check(BN_mask_bits(n->number, 8));
748
100
			str[0] = (char)BN_get_word(n->number);
749
100
			break;
750
		case BCODE_STRING:
751
3
			str[0] = value->u.string[0];
752
			break;
753
		}
754
103
		stack_free_value(value);
755
103
		push_string(bstrdup(str));
756
	}
757
}
758
759
static int
760
readreg(void)
761
40310
{
762
	int idx, ch1, ch2;
763
764
40310
	idx = readch();
765

40310
	if (idx == 0xff && bmachine.extended_regs) {
766
514
		ch1 = readch();
767
514
		ch2 = readch();
768
514
		if (ch1 == EOF || ch2 == EOF) {
769
			warnx("unexpected eof");
770
			idx = -1;
771
		} else
772
514
			idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
773
	}
774

40310
	if (idx < 0 || idx >= bmachine.reg_array_size) {
775
		warnx("internal error: reg num = %d", idx);
776
		idx = -1;
777
	}
778
40310
	return idx;
779
}
780
781
static void
782
load(void)
783
19534
{
784
	int		idx;
785
	struct value	*v, copy;
786
	struct number	*n;
787
788
19534
	idx = readreg();
789
19534
	if (idx >= 0) {
790
19534
		v = stack_tos(&bmachine.reg[idx]);
791
19534
		if (v == NULL) {
792
			n = new_number();
793
			bn_check(BN_zero(n->number));
794
			push_number(n);
795
		} else
796
19534
			push(stack_dup_value(v, &copy));
797
	}
798
19534
}
799
800
static void
801
store(void)
802
12829
{
803
	int		idx;
804
	struct value	*val;
805
806
12829
	idx = readreg();
807
12829
	if (idx >= 0) {
808
12829
		val = pop();
809
12829
		if (val == NULL) {
810
			return;
811
		}
812
12829
		stack_set_tos(&bmachine.reg[idx], val);
813
	}
814
}
815
816
static void
817
load_stack(void)
818
1086
{
819
	int		idx;
820
	struct stack	*stack;
821
	struct value	*value;
822
823
1086
	idx = readreg();
824
1086
	if (idx >= 0) {
825
1086
		stack = &bmachine.reg[idx];
826
1086
		value = NULL;
827
1086
		if (stack_size(stack) > 0) {
828
1086
			value = stack_pop(stack);
829
		}
830
1086
		if (value != NULL)
831
1086
			push(value);
832
		else
833
			warnx("stack register '%c' (0%o) is empty",
834
			    idx, idx);
835
	}
836
1086
}
837
838
static void
839
store_stack(void)
840
1085
{
841
	int		idx;
842
	struct value	*value;
843
844
1085
	idx = readreg();
845
1085
	if (idx >= 0) {
846
1085
		value = pop();
847
1085
		if (value == NULL)
848
			return;
849
1085
		stack_push(&bmachine.reg[idx], value);
850
	}
851
}
852
853
static void
854
load_array(void)
855
12
{
856
	int			reg;
857
	struct number		*inumber, *n;
858
	u_long			idx;
859
	struct stack		*stack;
860
	struct value		*v, copy;
861
862
12
	reg = readreg();
863
12
	if (reg >= 0) {
864
12
		inumber = pop_number();
865
12
		if (inumber == NULL)
866
			return;
867
12
		idx = get_ulong(inumber);
868
12
		if (BN_is_negative(inumber->number))
869
			warnx("negative idx");
870
12
		else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
871
			warnx("idx too big");
872
		else {
873
12
			stack = &bmachine.reg[reg];
874
12
			v = frame_retrieve(stack, idx);
875

15
			if (v == NULL || v->type == BCODE_NONE) {
876
3
				n = new_number();
877
3
				bn_check(BN_zero(n->number));
878
3
				push_number(n);
879
			}
880
			else
881
9
				push(stack_dup_value(v, &copy));
882
		}
883
12
		free_number(inumber);
884
	}
885
}
886
887
static void
888
store_array(void)
889
13
{
890
	int			reg;
891
	struct number		*inumber;
892
	u_long			idx;
893
	struct value		*value;
894
	struct stack		*stack;
895
896
13
	reg = readreg();
897
13
	if (reg >= 0) {
898
13
		inumber = pop_number();
899
13
		if (inumber == NULL)
900
			return;
901
13
		value = pop();
902
13
		if (value == NULL) {
903
			free_number(inumber);
904
			return;
905
		}
906
13
		idx = get_ulong(inumber);
907
13
		if (BN_is_negative(inumber->number)) {
908
			warnx("negative idx");
909
			stack_free_value(value);
910
13
		} else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
911
			warnx("idx too big");
912
			stack_free_value(value);
913
		} else {
914
13
			stack = &bmachine.reg[reg];
915
13
			frame_assign(stack, idx, value);
916
		}
917
13
		free_number(inumber);
918
	}
919
}
920
921
static void
922
push_line(void)
923
653
{
924
653
	push_string(read_string(&bmachine.readstack[bmachine.readsp]));
925
653
}
926
927
static void
928
comment(void)
929
1334
{
930
1334
	free(readline());
931
1334
}
932
933
static void
934
badd(void)
935
2400
{
936
	struct number	*a, *b;
937
	struct number	*r;
938
939
2400
	a = pop_number();
940
2400
	if (a == NULL)
941
		return;
942
2400
	b = pop_number();
943
2400
	if (b == NULL) {
944
		push_number(a);
945
		return;
946
	}
947
948
2400
	r = new_number();
949
2400
	r->scale = max(a->scale, b->scale);
950
2400
	if (r->scale > a->scale)
951
2
		normalize(a, r->scale);
952
2398
	else if (r->scale > b->scale)
953
6
		normalize(b, r->scale);
954
2400
	bn_check(BN_add(r->number, a->number, b->number));
955
2400
	push_number(r);
956
2400
	free_number(a);
957
2400
	free_number(b);
958
}
959
960
static void
961
bsub(void)
962
2463
{
963
	struct number	*a, *b;
964
	struct number	*r;
965
966
2463
	a = pop_number();
967
2463
	if (a == NULL)
968
		return;
969
2463
	b = pop_number();
970
2463
	if (b == NULL) {
971
		push_number(a);
972
		return;
973
	}
974
975
2463
	r = new_number();
976
977
2463
	r->scale = max(a->scale, b->scale);
978
2463
	if (r->scale > a->scale)
979
		normalize(a, r->scale);
980
2463
	else if (r->scale > b->scale)
981
6
		normalize(b, r->scale);
982
2463
	bn_check(BN_sub(r->number, b->number, a->number));
983
2463
	push_number(r);
984
2463
	free_number(a);
985
2463
	free_number(b);
986
}
987
988
void
989
bmul_number(struct number *r, struct number *a, struct number *b, u_int scale)
990
9522
{
991
	BN_CTX		*ctx;
992
993
	/* Create copies of the scales, since r might be equal to a or b */
994
9522
	u_int ascale = a->scale;
995
9522
	u_int bscale = b->scale;
996
9522
	u_int rscale = ascale + bscale;
997
998
9522
	ctx = BN_CTX_new();
999
9522
	bn_checkp(ctx);
1000
9522
	bn_check(BN_mul(r->number, a->number, b->number, ctx));
1001
9522
	BN_CTX_free(ctx);
1002
1003
9522
	r->scale = rscale;
1004

9522
	if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1005
737
		normalize(r, max(scale, max(ascale, bscale)));
1006
9522
}
1007
1008
static void
1009
bmul(void)
1010
4359
{
1011
	struct number	*a, *b;
1012
	struct number	*r;
1013
1014
4359
	a = pop_number();
1015
4359
	if (a == NULL)
1016
		return;
1017
4359
	b = pop_number();
1018
4359
	if (b == NULL) {
1019
		push_number(a);
1020
		return;
1021
	}
1022
1023
4359
	r = new_number();
1024
4359
	bmul_number(r, a, b, bmachine.scale);
1025
1026
4359
	push_number(r);
1027
4359
	free_number(a);
1028
4359
	free_number(b);
1029
}
1030
1031
static void
1032
bdiv(void)
1033
2868
{
1034
	struct number	*a, *b;
1035
	struct number	*r;
1036
	u_int		scale;
1037
	BN_CTX		*ctx;
1038
1039
2868
	a = pop_number();
1040
2868
	if (a == NULL)
1041
		return;
1042
2868
	b = pop_number();
1043
2868
	if (b == NULL) {
1044
		push_number(a);
1045
		return;
1046
	}
1047
1048
2868
	r = new_number();
1049
2868
	r->scale = bmachine.scale;
1050
2868
	scale = max(a->scale, b->scale);
1051
1052
2868
	if (BN_is_zero(a->number))
1053
		warnx("divide by zero");
1054
	else {
1055
2868
		normalize(a, scale);
1056
2868
		normalize(b, scale + r->scale);
1057
1058
2868
		ctx = BN_CTX_new();
1059
2868
		bn_checkp(ctx);
1060
2868
		bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1061
2868
		BN_CTX_free(ctx);
1062
	}
1063
2868
	push_number(r);
1064
2868
	free_number(a);
1065
2868
	free_number(b);
1066
}
1067
1068
static void
1069
bmod(void)
1070
1318
{
1071
	struct number	*a, *b;
1072
	struct number	*r;
1073
	u_int		scale;
1074
	BN_CTX		*ctx;
1075
1076
1318
	a = pop_number();
1077
1318
	if (a == NULL)
1078
		return;
1079
1318
	b = pop_number();
1080
1318
	if (b == NULL) {
1081
		push_number(a);
1082
		return;
1083
	}
1084
1085
1318
	r = new_number();
1086
1318
	scale = max(a->scale, b->scale);
1087
1318
	r->scale = max(b->scale, a->scale + bmachine.scale);
1088
1089
1318
	if (BN_is_zero(a->number))
1090
		warnx("remainder by zero");
1091
	else {
1092
1318
		normalize(a, scale);
1093
1318
		normalize(b, scale + bmachine.scale);
1094
1095
1318
		ctx = BN_CTX_new();
1096
1318
		bn_checkp(ctx);
1097
1318
		bn_check(BN_mod(r->number, b->number, a->number, ctx));
1098
1318
		BN_CTX_free(ctx);
1099
	}
1100
1318
	push_number(r);
1101
1318
	free_number(a);
1102
1318
	free_number(b);
1103
}
1104
1105
static void
1106
bdivmod(void)
1107
{
1108
	struct number	*a, *b;
1109
	struct number	*rdiv, *rmod;
1110
	u_int		scale;
1111
	BN_CTX		*ctx;
1112
1113
	a = pop_number();
1114
	if (a == NULL)
1115
		return;
1116
	b = pop_number();
1117
	if (b == NULL) {
1118
		push_number(a);
1119
		return;
1120
	}
1121
1122
	rdiv = new_number();
1123
	rmod = new_number();
1124
	rdiv->scale = bmachine.scale;
1125
	rmod->scale = max(b->scale, a->scale + bmachine.scale);
1126
	scale = max(a->scale, b->scale);
1127
1128
	if (BN_is_zero(a->number))
1129
		warnx("divide by zero");
1130
	else {
1131
		normalize(a, scale);
1132
		normalize(b, scale + bmachine.scale);
1133
1134
		ctx = BN_CTX_new();
1135
		bn_checkp(ctx);
1136
		bn_check(BN_div(rdiv->number, rmod->number,
1137
		    b->number, a->number, ctx));
1138
		BN_CTX_free(ctx);
1139
	}
1140
	push_number(rdiv);
1141
	push_number(rmod);
1142
	free_number(a);
1143
	free_number(b);
1144
}
1145
1146
static void
1147
bexp(void)
1148
615
{
1149
	struct number	*a, *p;
1150
	struct number	*r;
1151
	bool		neg;
1152
	u_int		rscale;
1153
1154
615
	p = pop_number();
1155
615
	if (p == NULL)
1156
		return;
1157
615
	a = pop_number();
1158
615
	if (a == NULL) {
1159
		push_number(p);
1160
		return;
1161
	}
1162
1163
615
	if (p->scale != 0) {
1164
		BIGNUM *i, *f;
1165
1
		i = BN_new();
1166
1
		bn_checkp(i);
1167
1
		f = BN_new();
1168
1
		bn_checkp(f);
1169
1
		split_number(p, i, f);
1170
1
		if (!BN_is_zero(f))
1171
			warnx("Runtime warning: non-zero fractional part in exponent");
1172
1
		BN_free(i);
1173
1
		BN_free(f);
1174
	}
1175
1176
615
	normalize(p, 0);
1177
1178
615
	neg = false;
1179
615
	if (BN_is_negative(p->number)) {
1180
11
		neg = true;
1181
11
		negate(p);
1182
11
		rscale = bmachine.scale;
1183
	} else {
1184
		/* Posix bc says min(a.scale * b, max(a.scale, scale) */
1185
		u_long	b;
1186
		u_int	m;
1187
1188
604
		b = BN_get_word(p->number);
1189
604
		m = max(a->scale, bmachine.scale);
1190
604
		rscale = a->scale * (u_int)b;
1191

604
		if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1192
		    b > UINT_MAX)))
1193
2
			rscale = m;
1194
	}
1195
1196
615
	if (BN_is_zero(p->number)) {
1197
296
		r = new_number();
1198
296
		bn_check(BN_one(r->number));
1199
296
		normalize(r, rscale);
1200
	} else {
1201
		u_int ascale, mscale;
1202
1203
319
		ascale = a->scale;
1204
678
		while (!BN_is_bit_set(p->number, 0)) {
1205
40
			ascale *= 2;
1206
40
			bmul_number(a, a, a, ascale);
1207
40
			bn_check(BN_rshift1(p->number, p->number));
1208
		}
1209
1210
319
		r = dup_number(a);
1211
319
		bn_check(BN_rshift1(p->number, p->number));
1212
1213
319
		mscale = ascale;
1214
770
		while (!BN_is_zero(p->number)) {
1215
132
			ascale *= 2;
1216
132
			bmul_number(a, a, a, ascale);
1217
132
			if (BN_is_bit_set(p->number, 0)) {
1218
89
				mscale += ascale;
1219
89
				bmul_number(r, r, a, mscale);
1220
			}
1221
132
			bn_check(BN_rshift1(p->number, p->number));
1222
		}
1223
1224
319
		if (neg) {
1225
			BN_CTX	*ctx;
1226
			BIGNUM	*one;
1227
1228
11
			one = BN_new();
1229
11
			bn_checkp(one);
1230
11
			bn_check(BN_one(one));
1231
11
			ctx = BN_CTX_new();
1232
11
			bn_checkp(ctx);
1233
11
			scale_number(one, r->scale + rscale);
1234
1235
11
			if (BN_is_zero(r->number))
1236
				warnx("divide by zero");
1237
			else
1238
11
				bn_check(BN_div(r->number, NULL, one,
1239
				    r->number, ctx));
1240
11
			BN_free(one);
1241
11
			BN_CTX_free(ctx);
1242
11
			r->scale = rscale;
1243
		} else
1244
308
			normalize(r, rscale);
1245
	}
1246
615
	push_number(r);
1247
615
	free_number(a);
1248
615
	free_number(p);
1249
}
1250
1251
static bool
1252
bsqrt_stop(const BIGNUM *x, const BIGNUM *y, u_int *onecount)
1253
11643
{
1254
	BIGNUM *r;
1255
	bool ret;
1256
1257
11643
	r = BN_new();
1258
11643
	bn_checkp(r);
1259
11643
	bn_check(BN_sub(r, x, y));
1260

11643
	if (BN_is_one(r))
1261
196
		(*onecount)++;
1262
11643
	ret = BN_is_zero(r);
1263
11643
	BN_free(r);
1264

11643
	return ret || *onecount > 1;
1265
}
1266
1267
static void
1268
bsqrt(void)
1269
4014
{
1270
	struct number	*n;
1271
	struct number	*r;
1272
	BIGNUM		*x, *y;
1273
	u_int		scale, onecount;
1274
	BN_CTX		*ctx;
1275
1276
4014
	onecount = 0;
1277
4014
	n = pop_number();
1278
4014
	if (n == NULL)
1279
		return;
1280
4014
	if (BN_is_zero(n->number)) {
1281
2
		r = new_number();
1282
2
		push_number(r);
1283
4012
	} else if (BN_is_negative(n->number))
1284
		warnx("square root of negative number");
1285
	else {
1286
4012
		scale = max(bmachine.scale, n->scale);
1287
4012
		normalize(n, 2*scale);
1288
4012
		x = BN_dup(n->number);
1289
4012
		bn_checkp(x);
1290
4012
		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1291
4012
		y = BN_new();
1292
4012
		bn_checkp(y);
1293
4012
		ctx = BN_CTX_new();
1294
4012
		bn_checkp(ctx);
1295
		for (;;) {
1296
11643
			bn_checkp(BN_copy(y, x));
1297
11643
			bn_check(BN_div(x, NULL, n->number, x, ctx));
1298
11643
			bn_check(BN_add(x, x, y));
1299
11643
			bn_check(BN_rshift1(x, x));
1300
11643
			if (bsqrt_stop(x, y, &onecount))
1301
4012
				break;
1302
		}
1303
4012
		r = bmalloc(sizeof(*r));
1304
4012
		r->scale = scale;
1305
4012
		r->number = y;
1306
4012
		BN_free(x);
1307
4012
		BN_CTX_free(ctx);
1308
4012
		push_number(r);
1309
	}
1310
1311
4014
	free_number(n);
1312
}
1313
1314
static void
1315
not(void)
1316
6
{
1317
	struct number	*a;
1318
1319
6
	a = pop_number();
1320
6
	if (a == NULL)
1321
		return;
1322
6
	a->scale = 0;
1323
6
	bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1324
6
	push_number(a);
1325
}
1326
1327
static void
1328
equal(void)
1329
2162
{
1330
2162
	compare(BCODE_EQUAL);
1331
2162
}
1332
1333
static void
1334
equal_numbers(void)
1335
9
{
1336
	struct number *a, *b, *r;
1337
1338
9
	a = pop_number();
1339
9
	if (a == NULL)
1340
		return;
1341
9
	b = pop_number();
1342
9
	if (b == NULL) {
1343
		push_number(a);
1344
		return;
1345
	}
1346
9
	r = new_number();
1347
9
	bn_check(BN_set_word(r->number,
1348
	    compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1349
9
	push_number(r);
1350
}
1351
1352
static void
1353
less_numbers(void)
1354
8
{
1355
	struct number *a, *b, *r;
1356
1357
8
	a = pop_number();
1358
8
	if (a == NULL)
1359
		return;
1360
8
	b = pop_number();
1361
8
	if (b == NULL) {
1362
		push_number(a);
1363
		return;
1364
	}
1365
8
	r = new_number();
1366
8
	bn_check(BN_set_word(r->number,
1367
	    compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1368
8
	push_number(r);
1369
}
1370
1371
static void
1372
lesseq_numbers(void)
1373
6
{
1374
	struct number *a, *b, *r;
1375
1376
6
	a = pop_number();
1377
6
	if (a == NULL)
1378
		return;
1379
6
	b = pop_number();
1380
6
	if (b == NULL) {
1381
		push_number(a);
1382
		return;
1383
	}
1384
6
	r = new_number();
1385
6
	bn_check(BN_set_word(r->number,
1386
	    compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1387
6
	push_number(r);
1388
}
1389
1390
static void
1391
not_equal(void)
1392
165
{
1393
165
	compare(BCODE_NOT_EQUAL);
1394
165
}
1395
1396
static void
1397
less(void)
1398
1964
{
1399
1964
	compare(BCODE_LESS);
1400
1964
}
1401
1402
static void
1403
not_compare(void)
1404
1468
{
1405

1468
	switch (readch()) {
1406
	case '<':
1407
1001
		not_less();
1408
1001
		break;
1409
	case '>':
1410
302
		not_greater();
1411
302
		break;
1412
	case '=':
1413
165
		not_equal();
1414
165
		break;
1415
	default:
1416
		unreadch();
1417
		(void)fprintf(stderr, "! command is deprecated\n");
1418
		break;
1419
	}
1420
1468
}
1421
1422
static void
1423
not_less(void)
1424
1001
{
1425
1001
	compare(BCODE_NOT_LESS);
1426
1001
}
1427
1428
static void
1429
greater(void)
1430
110
{
1431
110
	compare(BCODE_GREATER);
1432
110
}
1433
1434
static void
1435
not_greater(void)
1436
302
{
1437
302
	compare(BCODE_NOT_GREATER);
1438
302
}
1439
1440
static bool
1441
compare_numbers(enum bcode_compare type, struct number *a, struct number *b)
1442
5727
{
1443
	u_int	scale;
1444
	int	cmp;
1445
1446
11454
	scale = max(a->scale, b->scale);
1447
1448
5727
	if (scale > a->scale)
1449
14
		normalize(a, scale);
1450
5713
	else if (scale > b->scale)
1451
1
		normalize(b, scale);
1452
1453
5727
	cmp = BN_cmp(a->number, b->number);
1454
1455
5727
	free_number(a);
1456
5727
	free_number(b);
1457
1458

5727
	switch (type) {
1459
	case BCODE_EQUAL:
1460
2171
		return cmp == 0;
1461
	case BCODE_NOT_EQUAL:
1462
165
		return cmp != 0;
1463
	case BCODE_LESS:
1464
1972
		return cmp < 0;
1465
	case BCODE_NOT_LESS:
1466
1001
		return cmp >= 0;
1467
	case BCODE_GREATER:
1468
110
		return cmp > 0;
1469
	case BCODE_NOT_GREATER:
1470
308
		return cmp <= 0;
1471
	}
1472
	return false;
1473
}
1474
1475
static void
1476
compare(enum bcode_compare type)
1477
5704
{
1478
	int		idx, elseidx;
1479
	struct number	*a, *b;
1480
	bool		ok;
1481
	struct value	*v;
1482
1483
5704
	elseidx = NO_ELSE;
1484
5704
	idx = readreg();
1485
5704
	if (readch() == 'e')
1486
43
		elseidx = readreg();
1487
	else
1488
5661
		unreadch();
1489
1490
5704
	a = pop_number();
1491
5704
	if (a == NULL)
1492
		return;
1493
5704
	b = pop_number();
1494
5704
	if (b == NULL) {
1495
		push_number(a);
1496
		return;
1497
	}
1498
1499
5704
	ok = compare_numbers(type, a, b);
1500
1501

5704
	if (!ok && elseidx != NO_ELSE)
1502
24
		idx = elseidx;
1503
1504


5704
	if (idx >= 0 && (ok || (!ok && elseidx != NO_ELSE))) {
1505
2950
		v = stack_tos(&bmachine.reg[idx]);
1506
2950
		if (v == NULL)
1507
			warnx("register '%c' (0%o) is empty", idx, idx);
1508
		else {
1509

2950
			switch(v->type) {
1510
			case BCODE_NONE:
1511
				warnx("register '%c' (0%o) is empty", idx, idx);
1512
				break;
1513
			case BCODE_NUMBER:
1514
				warn("eval called with non-string argument");
1515
				break;
1516
			case BCODE_STRING:
1517
2950
				eval_string(bstrdup(v->u.string));
1518
				break;
1519
			}
1520
		}
1521
	}
1522
}
1523
1524
1525
static void
1526
nop(void)
1527
29982
{
1528
29982
}
1529
1530
static void
1531
quit(void)
1532
8
{
1533
8
	if (bmachine.readsp < 2)
1534
7
		exit(0);
1535
1
	src_free();
1536
1
	bmachine.readsp--;
1537
1
	src_free();
1538
1
	bmachine.readsp--;
1539
1
}
1540
1541
static void
1542
quitN(void)
1543
1018
{
1544
	struct number	*n;
1545
	u_long		i;
1546
1547
1018
	n = pop_number();
1548
1018
	if (n == NULL)
1549
		return;
1550
1018
	i = get_ulong(n);
1551
1018
	free_number(n);
1552
1018
	if (i == BN_MASK2 || i == 0)
1553
		warnx("Q command requires a number >= 1");
1554
1018
	else if (bmachine.readsp < i)
1555
		warnx("Q command argument exceeded string execution depth");
1556
	else {
1557
2043
		while (i-- > 0) {
1558
1025
			src_free();
1559
1025
			bmachine.readsp--;
1560
		}
1561
	}
1562
}
1563
1564
static void
1565
skipN(void)
1566
1
{
1567
	struct number	*n;
1568
	u_long		i;
1569
1570
1
	n = pop_number();
1571
1
	if (n == NULL)
1572
		return;
1573
1
	i = get_ulong(n);
1574
1
	if (i == BN_MASK2)
1575
		warnx("J command requires a number >= 0");
1576

1
	else if (i > 0 && bmachine.readsp < i)
1577
		warnx("J command argument exceeded string execution depth");
1578
	else {
1579
2
		while (i-- > 0) {
1580
1
			src_free();
1581
1
			bmachine.readsp--;
1582
		}
1583
1
		skip_until_mark();
1584
	}
1585
}
1586
1587
static void
1588
skip_until_mark(void)
1589
24
{
1590
	int ch;
1591
1592
	for (;;) {
1593
24
		ch = readch();
1594

24
		switch (ch) {
1595
		case 'M':
1596
			return;
1597
		case EOF:
1598
			errx(1, "mark not found");
1599
			return;
1600
		case 'l':
1601
		case 'L':
1602
		case 's':
1603
		case 'S':
1604
		case ':':
1605
		case ';':
1606
		case '<':
1607
		case '>':
1608
		case '=':
1609
1
			(void)readreg();
1610
1
			if (readch() == 'e')
1611
				(void)readreg();
1612
			else
1613
1
				unreadch();
1614
			break;
1615
		case '[':
1616
1
			free(read_string(&bmachine.readstack[bmachine.readsp]));
1617
1
			break;
1618
		case '!':
1619
3
			switch (ch = readch()) {
1620
				case '<':
1621
				case '>':
1622
				case '=':
1623
2
					(void)readreg();
1624
2
					if (readch() == 'e')
1625
1
						(void)readreg();
1626
					else
1627
1
						unreadch();
1628
					break;
1629
				default:
1630
1
					free(readline());
1631
					break;
1632
			}
1633
			break;
1634
		default:
1635
			break;
1636
		}
1637
	}
1638
}
1639
1640
static void
1641
parse_number(void)
1642
19398
{
1643
19398
	unreadch();
1644
19398
	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1645
	    bmachine.ibase));
1646
19398
}
1647
1648
static void
1649
unknown(void)
1650
{
1651
	int ch = bmachine.readstack[bmachine.readsp].lastchar;
1652
	warnx("%c (0%o) is unimplemented", ch, ch);
1653
}
1654
1655
static void
1656
eval_string(char *p)
1657
5223
{
1658
	int ch;
1659
1660
5223
	if (bmachine.readsp > 0) {
1661
		/* Check for tail call. Do not recurse in that case. */
1662
5121
		ch = readch();
1663
5121
		if (ch == EOF) {
1664
2823
			src_free();
1665
2823
			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1666
2823
			return;
1667
		} else
1668
2298
			unreadch();
1669
	}
1670
2400
	if (bmachine.readsp == bmachine.readstack_sz - 1) {
1671
10
		size_t newsz = bmachine.readstack_sz * 2;
1672
		struct source *stack;
1673
10
		stack = reallocarray(bmachine.readstack, newsz,
1674
		    sizeof(struct source));
1675
10
		if (stack == NULL)
1676
			err(1, "recursion too deep");
1677
10
		bmachine.readstack_sz = newsz;
1678
10
		bmachine.readstack = stack;
1679
	}
1680
2400
	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1681
}
1682
1683
static void
1684
eval_line(void)
1685
{
1686
	/* Always read from stdin */
1687
	struct source	in;
1688
	char		*p;
1689
1690
	clearerr(stdin);
1691
	src_setstream(&in, stdin);
1692
	p = (*in.vtable->readline)(&in);
1693
	eval_string(p);
1694
}
1695
1696
static void
1697
eval_tos(void)
1698
2273
{
1699
	char *p;
1700
1701
2273
	p = pop_string();
1702
2273
	if (p != NULL)
1703
2273
		eval_string(p);
1704
2273
}
1705
1706
void
1707
eval(void)
1708
130358
{
1709
	int	ch;
1710
1711
	for (;;) {
1712
130358
		ch = readch();
1713
130358
		if (ch == EOF) {
1714
1392
			if (bmachine.readsp == 0)
1715
20
				return;
1716
1372
			src_free();
1717
1372
			bmachine.readsp--;
1718
1372
			continue;
1719
		}
1720
128966
		if (bmachine.interrupted) {
1721
			if (bmachine.readsp > 0) {
1722
				src_free();
1723
				bmachine.readsp--;
1724
				continue;
1725
			} else
1726
				bmachine.interrupted = false;
1727
		}
1728
#ifdef DEBUGGING
1729
		(void)fprintf(stderr, "# %c\n", ch);
1730
		stack_print(stderr, &bmachine.stack, "* ",
1731
		    bmachine.obase);
1732
		(void)fprintf(stderr, "%zd =>\n", bmachine.readsp);
1733
#endif
1734
1735
128966
		if (0 <= ch && ch < UCHAR_MAX)
1736
128966
			(*jump_table[ch])();
1737
		else
1738
			warnx("internal error: opcode %d", ch);
1739
1740
#ifdef DEBUGGING
1741
		stack_print(stderr, &bmachine.stack, "* ",
1742
		    bmachine.obase);
1743
		(void)fprintf(stderr, "%zd ==\n", bmachine.readsp);
1744
#endif
1745
	}
1746
}