GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/dc/bcode.c Lines: 649 787 82.5 %
Date: 2017-11-13 Branches: 214 329 65.0 %

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
135
	bmachine.extended_regs = extended_registers;
233
135
	bmachine.reg_array_size = bmachine.extended_regs ?
234
	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
235
236
135
	bmachine.reg = calloc(bmachine.reg_array_size,
237
	    sizeof(bmachine.reg[0]));
238
135
	if (bmachine.reg == NULL)
239
		err(1, NULL);
240
241
69120
	for (i = 0; i < UCHAR_MAX; i++)
242
34425
		jump_table[i] = unknown;
243
19710
	for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
244
9720
		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
245
246
135
	stack_init(&bmachine.stack);
247
248
17764110
	for (i = 0; i < bmachine.reg_array_size; i++)
249
8881920
		stack_init(&bmachine.reg[i]);
250
251
135
	bmachine.readstack_sz = READSTACK_SIZE;
252
135
	bmachine.readstack = calloc(sizeof(struct source),
253
	    bmachine.readstack_sz);
254
135
	if (bmachine.readstack == NULL)
255
		err(1, NULL);
256
135
	bmachine.obase = bmachine.ibase = 10;
257
135
	(void)signal(SIGINT, sighandler);
258
135
}
259
260
u_int
261
bmachine_scale(void)
262
{
263
49020
	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
270
	bmachine.readsp = 0;
271
135
	bmachine.readstack[0] = *src;
272
135
}
273
274
static __inline int
275
readch(void)
276
{
277
1840190
	struct source *src = &bmachine.readstack[bmachine.readsp];
278
279
920095
	return src->vtable->readchar(src);
280
}
281
282
static __inline void
283
unreadch(void)
284
{
285
273590
	struct source *src = &bmachine.readstack[bmachine.readsp];
286
287
136795
	src->vtable->unreadchar(src);
288
136795
}
289
290
static __inline char *
291
readline(void)
292
{
293
13350
	struct source *src = &bmachine.readstack[bmachine.readsp];
294
295
6675
	return src->vtable->readline(src);
296
}
297
298
static __inline void
299
src_free(void)
300
{
301
52230
	struct source *src = &bmachine.readstack[bmachine.readsp];
302
303
26115
	src->vtable->free(src);
304
26115
}
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
221840
	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
252390
	if (s == 0)
348
69940
		return;
349
350
56255
	abs_scale = s > 0 ? s : -s;
351
352
56255
	if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
353
42140
		if (s > 0)
354
42120
			bn_check(BN_mul_word(n, factors[abs_scale]));
355
		else
356
20
			(void)BN_div_word(n, factors[abs_scale]);
357
	} else {
358
		BIGNUM *a, *p;
359
		BN_CTX *ctx;
360
361
14115
		a = BN_new();
362
14115
		bn_checkp(a);
363
14115
		p = BN_new();
364
14115
		bn_checkp(p);
365
14115
		ctx = BN_CTX_new();
366
14115
		bn_checkp(ctx);
367
368
14115
		bn_check(BN_set_word(a, 10));
369
14115
		bn_check(BN_set_word(p, abs_scale));
370
14115
		bn_check(BN_exp(a, a, p, ctx));
371
14115
		if (s > 0)
372
10535
			bn_check(BN_mul(n, n, a, ctx));
373
		else
374
3580
			bn_check(BN_div(n, NULL, n, a, ctx));
375
14115
		BN_CTX_free(ctx);
376
14115
		BN_free(a);
377
14115
		BN_free(p);
378
	}
379
182450
}
380
381
void
382
split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
383
{
384
	u_long rem;
385
386
103290
	bn_checkp(BN_copy(i, n->number));
387
388
51645
	if (n->scale == 0 && f != NULL)
389
16530
		bn_check(BN_set_word(f, 0));
390
35115
	else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
391
31905
		rem = BN_div_word(i, factors[n->scale]);
392
31905
		if (f != NULL)
393
10565
			bn_check(BN_set_word(f, rem));
394
	} else {
395
		BIGNUM *a, *p;
396
		BN_CTX *ctx;
397
398
3210
		a = BN_new();
399
3210
		bn_checkp(a);
400
3210
		p = BN_new();
401
3210
		bn_checkp(p);
402
3210
		ctx = BN_CTX_new();
403
3210
		bn_checkp(ctx);
404
405
3210
		bn_check(BN_set_word(a, 10));
406
3210
		bn_check(BN_set_word(p, n->scale));
407
3210
		bn_check(BN_exp(a, a, p, ctx));
408
3210
		bn_check(BN_div(i, f, n->number, a, ctx));
409
3210
		BN_CTX_free(ctx);
410
3210
		BN_free(a);
411
3210
		BN_free(p);
412
	}
413
51645
}
414
415
void
416
normalize(struct number *n, u_int s)
417
{
418
230360
	scale_number(n->number, s - n->scale);
419
115180
	n->scale = s;
420
115180
}
421
422
static u_long
423
get_ulong(struct number *n)
424
{
425
16900
	normalize(n, 0);
426
8450
	return BN_get_word(n->number);
427
}
428
429
void
430
negate(struct number *n)
431
{
432
460
	BN_set_negative(n->number, !BN_is_negative(n->number));
433
230
}
434
435
static __inline void
436
push_number(struct number *n)
437
{
438
378100
	stack_pushnumber(&bmachine.stack, n);
439
189050
}
440
441
static __inline void
442
push_string(char *string)
443
{
444
7560
	stack_pushstring(&bmachine.stack, string);
445
3780
}
446
447
static __inline void
448
push(struct value *v)
449
{
450
206290
	stack_push(&bmachine.stack, v);
451
103145
}
452
453
static __inline struct value *
454
tos(void)
455
{
456
50450
	return stack_tos(&bmachine.stack);
457
}
458
459
static __inline struct value *
460
pop(void)
461
{
462
179040
	return stack_pop(&bmachine.stack);
463
}
464
465
static __inline struct number *
466
pop_number(void)
467
{
468
452100
	return stack_popnumber(&bmachine.stack);
469
}
470
471
static __inline char *
472
pop_string(void)
473
{
474
22730
	return stack_popstring(&bmachine.stack);
475
}
476
477
static __inline void
478
clear_stack(void)
479
{
480
30
	stack_clear(&bmachine.stack);
481
15
}
482
483
static __inline void
484
print_stack(void)
485
{
486
80
	stack_print(stdout, &bmachine.stack, "", bmachine.obase);
487
40
}
488
489
static __inline void
490
print_tos(void)
491
{
492
50450
	struct value *value = tos();
493
25225
	if (value != NULL) {
494
25225
		print_value(stdout, value, "", bmachine.obase);
495
50450
		(void)putchar('\n');
496
	}
497
	else
498
		warnx("stack empty");
499
25225
}
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
33560
	struct value *value = pop();
517
518
16780
	if (value != NULL) {
519
33560
		switch (value->type) {
520
		case BCODE_NONE:
521
			break;
522
		case BCODE_NUMBER:
523
9875
			normalize(value->u.num, 0);
524
9875
			print_ascii(stdout, value->u.num);
525
9875
			(void)fflush(stdout);
526
9875
			break;
527
		case BCODE_STRING:
528
6905
			(void)fputs(value->u.string, stdout);
529
6905
			(void)fflush(stdout);
530
6905
			break;
531
		}
532
16780
		stack_free_value(value);
533
16780
	}
534
16780
}
535
536
static void
537
pop_printn(void)
538
{
539
1790
	struct value *value = pop();
540
541
895
	if (value != NULL) {
542
895
		print_value(stdout, value, "", bmachine.obase);
543
895
		(void)fflush(stdout);
544
895
		stack_free_value(value);
545
895
	}
546
895
}
547
548
static __inline void
549
dup(void)
550
{
551
62770
	stack_dup(&bmachine.stack);
552
31385
}
553
554
static void
555
swap(void)
556
{
557
70
	stack_swap(&bmachine.stack);
558
35
}
559
560
static void
561
drop(void)
562
{
563
30
	struct value *v = pop();
564
15
	if (v != NULL)
565
15
		stack_free_value(v);
566
15
}
567
568
static void
569
get_scale(void)
570
{
571
	struct number	*n;
572
573
50
	n = new_number();
574
25
	bn_check(BN_set_word(n->number, bmachine.scale));
575
25
	push_number(n);
576
25
}
577
578
static void
579
set_scale(void)
580
{
581
	struct number	*n;
582
	u_long		scale;
583
584
130
	n = pop_number();
585
65
	if (n != NULL) {
586
65
		if (BN_is_negative(n->number))
587
			warnx("scale must be a nonnegative number");
588
		else {
589
65
			scale = get_ulong(n);
590
65
			if (scale != BN_MASK2 && scale <= UINT_MAX)
591
65
				bmachine.scale = (u_int)scale;
592
			else
593
				warnx("scale too large");
594
			}
595
65
		free_number(n);
596
65
	}
597
65
}
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
6290
	n = pop_number();
616
3145
	if (n != NULL) {
617
3145
		base = get_ulong(n);
618
3145
		if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
619
3145
			bmachine.obase = (u_int)base;
620
		else
621
			warnx("output base must be a number greater than 1");
622
3145
		free_number(n);
623
3145
	}
624
3145
}
625
626
static void
627
get_ibase(void)
628
{
629
	struct number *n;
630
631
	n = new_number();
632
	bn_check(BN_set_word(n->number, bmachine.ibase));
633
	push_number(n);
634
}
635
636
static void
637
set_ibase(void)
638
{
639
	struct number	*n;
640
	u_long		base;
641
642
40
	n = pop_number();
643
20
	if (n != NULL) {
644
20
		base = get_ulong(n);
645
20
		if (base != BN_MASK2 && 2 <= base && base <= 16)
646
20
			bmachine.ibase = (u_int)base;
647
		else
648
			warnx("input base must be a number between 2 and 16 "
649
			    "(inclusive)");
650
20
		free_number(n);
651
20
	}
652
20
}
653
654
static void
655
stackdepth(void)
656
{
657
	size_t i;
658
	struct number *n;
659
660
20
	i = stack_size(&bmachine.stack);
661
10
	n = new_number();
662
10
	bn_check(BN_set_word(n->number, i));
663
10
	push_number(n);
664
10
}
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
70
	value = pop();
675
35
	if (value != NULL) {
676
60
		switch (value->type) {
677
		case BCODE_NONE:
678
			return;
679
		case BCODE_NUMBER:
680
25
			scale = value->u.num->scale;
681
25
			break;
682
		case BCODE_STRING:
683
			break;
684
		}
685
35
		stack_free_value(value);
686
35
		n = new_number();
687
35
		bn_check(BN_set_word(n->number, scale));
688
35
		push_number(n);
689
35
	}
690
70
}
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
3260
	if (BN_is_zero(n->number))
699
20
		return n->scale ? n->scale : 1;
700
701
1620
	int_part = new_number();
702
1620
	fract_part = new_number();
703
1620
	fract_part->scale = n->scale;
704
1620
	split_number(n, int_part->number, fract_part->number);
705
706
	i = 0;
707
15940
	while (!BN_is_zero(int_part->number)) {
708
6350
		(void)BN_div_word(int_part->number, 10);
709
6350
		i++;
710
	}
711
1620
	free_number(int_part);
712
1620
	free_number(fract_part);
713
1620
	return i + n->scale;
714
1630
}
715
716
static void
717
num_digits(void)
718
{
719
	struct value	*value;
720
	size_t		digits;
721
	struct number	*n = NULL;
722
723
3290
	value = pop();
724
1645
	if (value != NULL) {
725

3290
		switch (value->type) {
726
		case BCODE_NONE:
727
			return;
728
		case BCODE_NUMBER:
729
1630
			digits = count_digits(value->u.num);
730
1630
			n = new_number();
731
1630
			bn_check(BN_set_word(n->number, digits));
732
1630
			break;
733
		case BCODE_STRING:
734
15
			digits = strlen(value->u.string);
735
15
			n = new_number();
736
15
			bn_check(BN_set_word(n->number, digits));
737
15
			break;
738
		}
739
1645
		stack_free_value(value);
740
1645
		push_number(n);
741
1645
	}
742
3290
}
743
744
static void
745
to_ascii(void)
746
{
747
1030
	char		str[2];
748
	struct value	*value;
749
	struct number	*n;
750
751
515
	value = pop();
752
515
	if (value != NULL) {
753
1030
		str[1] = '\0';
754

1030
		switch (value->type) {
755
		case BCODE_NONE:
756
			return;
757
		case BCODE_NUMBER:
758
500
			n = value->u.num;
759
500
			normalize(n, 0);
760
500
			if (BN_num_bits(n->number) > 8)
761
5
				bn_check(BN_mask_bits(n->number, 8));
762
500
			str[0] = (char)BN_get_word(n->number);
763
500
			break;
764
		case BCODE_STRING:
765
15
			str[0] = value->u.string[0];
766
15
			break;
767
		}
768
1030
		stack_free_value(value);
769
515
		push_string(bstrdup(str));
770
515
	}
771
1030
}
772
773
static int
774
readreg(void)
775
{
776
	int idx, ch1, ch2;
777
778
403100
	idx = readch();
779

204120
	if (idx == 0xff && bmachine.extended_regs) {
780
2570
		ch1 = readch();
781
2570
		ch2 = readch();
782
2570
		if (ch1 == EOF || ch2 == EOF) {
783
			warnx("unexpected eof");
784
			idx = -1;
785
		} else
786
2570
			idx = (ch1 << 8) + ch2 + UCHAR_MAX + 1;
787
	}
788

403100
	if (idx < 0 || idx >= bmachine.reg_array_size) {
789
		warnx("internal error: reg num = %d", idx);
790
		idx = -1;
791
	}
792
201550
	return idx;
793
}
794
795
static void
796
load(void)
797
{
798
	int		idx;
799
195340
	struct value	*v, copy;
800
	struct number	*n;
801
802
97670
	idx = readreg();
803
97670
	if (idx >= 0) {
804
97670
		v = stack_tos(&bmachine.reg[idx]);
805
97670
		if (v == NULL) {
806
			n = new_number();
807
			bn_check(BN_set_word(n->number, 0));
808
			push_number(n);
809
		} else
810
97670
			push(stack_dup_value(v, &copy));
811
	}
812
97670
}
813
814
static void
815
store(void)
816
{
817
	int		idx;
818
	struct value	*val;
819
820
128290
	idx = readreg();
821
64145
	if (idx >= 0) {
822
64145
		val = pop();
823
64145
		if (val == NULL) {
824
			return;
825
		}
826
64145
		stack_set_tos(&bmachine.reg[idx], val);
827
64145
	}
828
128290
}
829
830
static void
831
load_stack(void)
832
{
833
	int		idx;
834
	struct stack	*stack;
835
	struct value	*value;
836
837
10860
	idx = readreg();
838
5430
	if (idx >= 0) {
839
5430
		stack = &bmachine.reg[idx];
840
		value = NULL;
841
5430
		if (stack_size(stack) > 0) {
842
5430
			value = stack_pop(stack);
843
5430
		}
844
5430
		if (value != NULL)
845
5430
			push(value);
846
		else
847
			warnx("stack register '%c' (0%o) is empty",
848
			    idx, idx);
849
	}
850
5430
}
851
852
static void
853
store_stack(void)
854
{
855
	int		idx;
856
	struct value	*value;
857
858
10850
	idx = readreg();
859
5425
	if (idx >= 0) {
860
5425
		value = pop();
861
5425
		if (value == NULL)
862
			return;
863
5425
		stack_push(&bmachine.reg[idx], value);
864
5425
	}
865
10850
}
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
120
	struct value		*v, copy;
875
876
60
	reg = readreg();
877
60
	if (reg >= 0) {
878
60
		inumber = pop_number();
879
60
		if (inumber == NULL)
880
			return;
881
60
		idx = get_ulong(inumber);
882
60
		if (BN_is_negative(inumber->number))
883
			warnx("negative idx");
884
60
		else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX)
885
			warnx("idx too big");
886
		else {
887
60
			stack = &bmachine.reg[reg];
888
60
			v = frame_retrieve(stack, idx);
889

105
			if (v == NULL || v->type == BCODE_NONE) {
890
15
				n = new_number();
891
15
				bn_check(BN_set_word(n->number, 0));
892
15
				push_number(n);
893
15
			}
894
			else
895
45
				push(stack_dup_value(v, &copy));
896
		}
897
60
		free_number(inumber);
898
60
	}
899
120
}
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
130
	reg = readreg();
911
65
	if (reg >= 0) {
912
65
		inumber = pop_number();
913
65
		if (inumber == NULL)
914
			return;
915
65
		value = pop();
916
65
		if (value == NULL) {
917
			free_number(inumber);
918
			return;
919
		}
920
65
		idx = get_ulong(inumber);
921
65
		if (BN_is_negative(inumber->number)) {
922
			warnx("negative idx");
923
			stack_free_value(value);
924
65
		} else if (idx == BN_MASK2 || idx > MAX_ARRAY_INDEX) {
925
			warnx("idx too big");
926
			stack_free_value(value);
927
		} else {
928
65
			stack = &bmachine.reg[reg];
929
65
			frame_assign(stack, idx, value);
930
		}
931
65
		free_number(inumber);
932
65
	}
933
130
}
934
935
static void
936
push_line(void)
937
{
938
6530
	push_string(read_string(&bmachine.readstack[bmachine.readsp]));
939
3265
}
940
941
static void
942
comment(void)
943
{
944
13340
	free(readline());
945
6670
}
946
947
static void
948
badd(void)
949
{
950
	struct number	*a, *b;
951
	struct number	*r;
952
953
24000
	a = pop_number();
954
12000
	if (a == NULL)
955
		return;
956
12000
	b = pop_number();
957
12000
	if (b == NULL) {
958
		push_number(a);
959
		return;
960
	}
961
962
12000
	r = new_number();
963
12000
	r->scale = max(a->scale, b->scale);
964
12000
	if (r->scale > a->scale)
965
10
		normalize(a, r->scale);
966
11990
	else if (r->scale > b->scale)
967
30
		normalize(b, r->scale);
968
12000
	bn_check(BN_add(r->number, a->number, b->number));
969
12000
	push_number(r);
970
12000
	free_number(a);
971
12000
	free_number(b);
972
24000
}
973
974
static void
975
bsub(void)
976
{
977
	struct number	*a, *b;
978
	struct number	*r;
979
980
24630
	a = pop_number();
981
12315
	if (a == NULL)
982
		return;
983
12315
	b = pop_number();
984
12315
	if (b == NULL) {
985
		push_number(a);
986
		return;
987
	}
988
989
12315
	r = new_number();
990
991
12315
	r->scale = max(a->scale, b->scale);
992
12315
	if (r->scale > a->scale)
993
		normalize(a, r->scale);
994
12315
	else if (r->scale > b->scale)
995
30
		normalize(b, r->scale);
996
12315
	bn_check(BN_sub(r->number, b->number, a->number));
997
12315
	push_number(r);
998
12315
	free_number(a);
999
12315
	free_number(b);
1000
24630
}
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
95220
	u_int ascale = a->scale;
1009
47610
	u_int bscale = b->scale;
1010
47610
	u_int rscale = ascale + bscale;
1011
1012
47610
	ctx = BN_CTX_new();
1013
47610
	bn_checkp(ctx);
1014
47610
	bn_check(BN_mul(r->number, a->number, b->number, ctx));
1015
47610
	BN_CTX_free(ctx);
1016
1017
47610
	r->scale = rscale;
1018

76390
	if (rscale > bmachine.scale && rscale > ascale && rscale > bscale)
1019
3685
		normalize(r, max(scale, max(ascale, bscale)));
1020
47610
}
1021
1022
static void
1023
bmul(void)
1024
{
1025
	struct number	*a, *b;
1026
	struct number	*r;
1027
1028
43590
	a = pop_number();
1029
21795
	if (a == NULL)
1030
		return;
1031
21795
	b = pop_number();
1032
21795
	if (b == NULL) {
1033
		push_number(a);
1034
		return;
1035
	}
1036
1037
21795
	r = new_number();
1038
21795
	bmul_number(r, a, b, bmachine.scale);
1039
1040
21795
	push_number(r);
1041
21795
	free_number(a);
1042
21795
	free_number(b);
1043
43590
}
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
28680
	a = pop_number();
1054
14340
	if (a == NULL)
1055
		return;
1056
14340
	b = pop_number();
1057
14340
	if (b == NULL) {
1058
		push_number(a);
1059
		return;
1060
	}
1061
1062
14340
	r = new_number();
1063
14340
	r->scale = bmachine.scale;
1064
14340
	scale = max(a->scale, b->scale);
1065
1066
14340
	if (BN_is_zero(a->number))
1067
		warnx("divide by zero");
1068
	else {
1069
14340
		normalize(a, scale);
1070
14340
		normalize(b, scale + r->scale);
1071
1072
14340
		ctx = BN_CTX_new();
1073
14340
		bn_checkp(ctx);
1074
14340
		bn_check(BN_div(r->number, NULL, b->number, a->number, ctx));
1075
14340
		BN_CTX_free(ctx);
1076
	}
1077
14340
	push_number(r);
1078
14340
	free_number(a);
1079
14340
	free_number(b);
1080
28680
}
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
13180
	a = pop_number();
1091
6590
	if (a == NULL)
1092
		return;
1093
6590
	b = pop_number();
1094
6590
	if (b == NULL) {
1095
		push_number(a);
1096
		return;
1097
	}
1098
1099
6590
	r = new_number();
1100
6590
	scale = max(a->scale, b->scale);
1101
6590
	r->scale = max(b->scale, a->scale + bmachine.scale);
1102
1103
6590
	if (BN_is_zero(a->number))
1104
		warnx("remainder by zero");
1105
	else {
1106
6590
		normalize(a, scale);
1107
6590
		normalize(b, scale + bmachine.scale);
1108
1109
6590
		ctx = BN_CTX_new();
1110
6590
		bn_checkp(ctx);
1111
6590
		bn_check(BN_mod(r->number, b->number, a->number, ctx));
1112
6590
		BN_CTX_free(ctx);
1113
	}
1114
6590
	push_number(r);
1115
6590
	free_number(a);
1116
6590
	free_number(b);
1117
13180
}
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
6150
	p = pop_number();
1169
3075
	if (p == NULL)
1170
		return;
1171
3075
	a = pop_number();
1172
3075
	if (a == NULL) {
1173
		push_number(p);
1174
		return;
1175
	}
1176
1177
3075
	if (p->scale != 0) {
1178
		BIGNUM *i, *f;
1179
5
		i = BN_new();
1180
5
		bn_checkp(i);
1181
5
		f = BN_new();
1182
5
		bn_checkp(f);
1183
5
		split_number(p, i, f);
1184
5
		if (!BN_is_zero(f))
1185
			warnx("Runtime warning: non-zero fractional part in exponent");
1186
5
		BN_free(i);
1187
5
		BN_free(f);
1188
5
	}
1189
1190
3075
	normalize(p, 0);
1191
1192
	neg = false;
1193
3075
	if (BN_is_negative(p->number)) {
1194
		neg = true;
1195
55
		negate(p);
1196
55
		rscale = bmachine.scale;
1197
55
	} else {
1198
		/* Posix bc says min(a.scale * b, max(a.scale, scale) */
1199
		u_long	b;
1200
		u_int	m;
1201
1202
3020
		b = BN_get_word(p->number);
1203
3020
		m = max(a->scale, bmachine.scale);
1204
3020
		rscale = a->scale * (u_int)b;
1205

6070
		if (rscale > m || (a->scale > 0 && (b == BN_MASK2 ||
1206
20
		    b > UINT_MAX)))
1207
10
			rscale = m;
1208
	}
1209
1210
3075
	if (BN_is_zero(p->number)) {
1211
1480
		r = new_number();
1212
1480
		bn_check(BN_one(r->number));
1213
1480
		normalize(r, rscale);
1214
1480
	} else {
1215
		u_int ascale, mscale;
1216
1217
1595
		ascale = a->scale;
1218
3590
		while (!BN_is_bit_set(p->number, 0)) {
1219
200
			ascale *= 2;
1220
200
			bmul_number(a, a, a, ascale);
1221
200
			bn_check(BN_rshift1(p->number, p->number));
1222
		}
1223
1224
1595
		r = dup_number(a);
1225
1595
		bn_check(BN_rshift1(p->number, p->number));
1226
1227
		mscale = ascale;
1228
4510
		while (!BN_is_zero(p->number)) {
1229
660
			ascale *= 2;
1230
660
			bmul_number(a, a, a, ascale);
1231
660
			if (BN_is_bit_set(p->number, 0)) {
1232
445
				mscale += ascale;
1233
445
				bmul_number(r, r, a, mscale);
1234
445
			}
1235
660
			bn_check(BN_rshift1(p->number, p->number));
1236
		}
1237
1238
1595
		if (neg) {
1239
			BN_CTX	*ctx;
1240
			BIGNUM	*one;
1241
1242
55
			one = BN_new();
1243
55
			bn_checkp(one);
1244
55
			bn_check(BN_one(one));
1245
55
			ctx = BN_CTX_new();
1246
55
			bn_checkp(ctx);
1247
55
			scale_number(one, r->scale + rscale);
1248
1249
55
			if (BN_is_zero(r->number))
1250
				warnx("divide by zero");
1251
			else
1252
55
				bn_check(BN_div(r->number, NULL, one,
1253
				    r->number, ctx));
1254
55
			BN_free(one);
1255
55
			BN_CTX_free(ctx);
1256
55
			r->scale = rscale;
1257
55
		} else
1258
1540
			normalize(r, rscale);
1259
	}
1260
3075
	push_number(r);
1261
3075
	free_number(a);
1262
3075
	free_number(p);
1263
6150
}
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
116430
	r = BN_new();
1272
58215
	bn_checkp(r);
1273
58215
	bn_check(BN_sub(r, x, y));
1274

104520
	if (BN_is_one(r))
1275
980
		(*onecount)++;
1276
58215
	ret = BN_is_zero(r);
1277
58215
	BN_free(r);
1278
154810
	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
40140
	u_int		scale, onecount;
1288
	BN_CTX		*ctx;
1289
1290
20070
	onecount = 0;
1291
20070
	n = pop_number();
1292
20070
	if (n == NULL)
1293
		return;
1294
20070
	if (BN_is_zero(n->number)) {
1295
10
		r = new_number();
1296
10
		push_number(r);
1297
20070
	} else if (BN_is_negative(n->number))
1298
		warnx("square root of negative number");
1299
	else {
1300
20060
		scale = max(bmachine.scale, n->scale);
1301
20060
		normalize(n, 2*scale);
1302
20060
		x = BN_dup(n->number);
1303
20060
		bn_checkp(x);
1304
20060
		bn_check(BN_rshift(x, x, BN_num_bits(x)/2));
1305
20060
		y = BN_new();
1306
20060
		bn_checkp(y);
1307
20060
		ctx = BN_CTX_new();
1308
20060
		bn_checkp(ctx);
1309
58215
		for (;;) {
1310
58215
			bn_checkp(BN_copy(y, x));
1311
58215
			bn_check(BN_div(x, NULL, n->number, x, ctx));
1312
58215
			bn_check(BN_add(x, x, y));
1313
58215
			bn_check(BN_rshift1(x, x));
1314
58215
			if (bsqrt_stop(x, y, &onecount))
1315
				break;
1316
		}
1317
20060
		r = bmalloc(sizeof(*r));
1318
20060
		r->scale = scale;
1319
20060
		r->number = y;
1320
20060
		BN_free(x);
1321
20060
		BN_CTX_free(ctx);
1322
20060
		push_number(r);
1323
	}
1324
1325
20070
	free_number(n);
1326
40140
}
1327
1328
static void
1329
not(void)
1330
{
1331
	struct number	*a;
1332
1333
60
	a = pop_number();
1334
30
	if (a == NULL)
1335
		return;
1336
30
	a->scale = 0;
1337
30
	bn_check(BN_set_word(a->number, BN_get_word(a->number) ? 0 : 1));
1338
30
	push_number(a);
1339
60
}
1340
1341
static void
1342
equal(void)
1343
{
1344
21620
	compare(BCODE_EQUAL);
1345
10810
}
1346
1347
static void
1348
equal_numbers(void)
1349
{
1350
	struct number *a, *b, *r;
1351
1352
90
	a = pop_number();
1353
45
	if (a == NULL)
1354
		return;
1355
45
	b = pop_number();
1356
45
	if (b == NULL) {
1357
		push_number(a);
1358
		return;
1359
	}
1360
45
	r = new_number();
1361
90
	bn_check(BN_set_word(r->number,
1362
45
	    compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0));
1363
45
	push_number(r);
1364
90
}
1365
1366
static void
1367
less_numbers(void)
1368
{
1369
	struct number *a, *b, *r;
1370
1371
80
	a = pop_number();
1372
40
	if (a == NULL)
1373
		return;
1374
40
	b = pop_number();
1375
40
	if (b == NULL) {
1376
		push_number(a);
1377
		return;
1378
	}
1379
40
	r = new_number();
1380
80
	bn_check(BN_set_word(r->number,
1381
40
	    compare_numbers(BCODE_LESS, a, b) ? 1 : 0));
1382
40
	push_number(r);
1383
80
}
1384
1385
static void
1386
lesseq_numbers(void)
1387
{
1388
	struct number *a, *b, *r;
1389
1390
60
	a = pop_number();
1391
30
	if (a == NULL)
1392
		return;
1393
30
	b = pop_number();
1394
30
	if (b == NULL) {
1395
		push_number(a);
1396
		return;
1397
	}
1398
30
	r = new_number();
1399
60
	bn_check(BN_set_word(r->number,
1400
30
	    compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0));
1401
30
	push_number(r);
1402
60
}
1403
1404
static void
1405
not_equal(void)
1406
{
1407
1650
	compare(BCODE_NOT_EQUAL);
1408
825
}
1409
1410
static void
1411
less(void)
1412
{
1413
19640
	compare(BCODE_LESS);
1414
9820
}
1415
1416
static void
1417
not_compare(void)
1418
{
1419

14680
	switch (readch()) {
1420
	case '<':
1421
5005
		not_less();
1422
5005
		break;
1423
	case '>':
1424
1510
		not_greater();
1425
1510
		break;
1426
	case '=':
1427
825
		not_equal();
1428
825
		break;
1429
	default:
1430
		unreadch();
1431
		(void)fprintf(stderr, "! command is deprecated\n");
1432
		break;
1433
	}
1434
7340
}
1435
1436
static void
1437
not_less(void)
1438
{
1439
10010
	compare(BCODE_NOT_LESS);
1440
5005
}
1441
1442
static void
1443
greater(void)
1444
{
1445
1100
	compare(BCODE_GREATER);
1446
550
}
1447
1448
static void
1449
not_greater(void)
1450
{
1451
3020
	compare(BCODE_NOT_GREATER);
1452
1510
}
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
57270
	scale = max(a->scale, b->scale);
1461
1462
28635
	if (scale > a->scale)
1463
70
		normalize(a, scale);
1464
28565
	else if (scale > b->scale)
1465
5
		normalize(b, scale);
1466
1467
28635
	cmp = BN_cmp(a->number, b->number);
1468
1469
28635
	free_number(a);
1470
28635
	free_number(b);
1471
1472

28635
	switch (type) {
1473
	case BCODE_EQUAL:
1474
10855
		return cmp == 0;
1475
	case BCODE_NOT_EQUAL:
1476
825
		return cmp != 0;
1477
	case BCODE_LESS:
1478
9860
		return cmp < 0;
1479
	case BCODE_NOT_LESS:
1480
5005
		return cmp >= 0;
1481
	case BCODE_GREATER:
1482
550
		return cmp > 0;
1483
	case BCODE_NOT_GREATER:
1484
1540
		return cmp <= 0;
1485
	}
1486
	return false;
1487
28635
}
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
57040
	idx = readreg();
1499
28520
	if (readch() == 'e')
1500
215
		elseidx = readreg();
1501
	else
1502
28305
		unreadch();
1503
1504
28520
	a = pop_number();
1505
28520
	if (a == NULL)
1506
		return;
1507
28520
	b = pop_number();
1508
28520
	if (b == NULL) {
1509
		push_number(a);
1510
		return;
1511
	}
1512
1513
28520
	ok = compare_numbers(type, a, b);
1514
1515
28520
	if (!ok && elseidx != NO_ELSE)
1516
120
		idx = elseidx;
1517
1518

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

38245
			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
14750
				eval_string(bstrdup(v->u.string));
1532
14750
				break;
1533
			}
1534
		}
1535
	}
1536
57040
}
1537
1538
1539
static void
1540
nop(void)
1541
{
1542
299820
}
1543
1544
static void
1545
quit(void)
1546
{
1547
80
	if (bmachine.readsp < 2)
1548
		exit(0);
1549
5
	src_free();
1550
5
	bmachine.readsp--;
1551
5
	src_free();
1552
5
	bmachine.readsp--;
1553
5
}
1554
1555
static void
1556
quitN(void)
1557
{
1558
	struct number	*n;
1559
	u_long		i;
1560
1561
10180
	n = pop_number();
1562
5090
	if (n == NULL)
1563
		return;
1564
5090
	i = get_ulong(n);
1565
5090
	free_number(n);
1566
5090
	if (i == BN_MASK2 || i == 0)
1567
		warnx("Q command requires a number >= 1");
1568
5090
	else if (bmachine.readsp < i)
1569
		warnx("Q command argument exceeded string execution depth");
1570
	else {
1571
20430
		while (i-- > 0) {
1572
5125
			src_free();
1573
5125
			bmachine.readsp--;
1574
		}
1575
	}
1576
10180
}
1577
1578
static void
1579
skipN(void)
1580
{
1581
	struct number	*n;
1582
	u_long		i;
1583
1584
10
	n = pop_number();
1585
5
	if (n == NULL)
1586
		return;
1587
5
	i = get_ulong(n);
1588
5
	if (i == BN_MASK2)
1589
		warnx("J command requires a number >= 0");
1590

10
	else if (i > 0 && bmachine.readsp < i)
1591
		warnx("J command argument exceeded string execution depth");
1592
	else {
1593
20
		while (i-- > 0) {
1594
5
			src_free();
1595
5
			bmachine.readsp--;
1596
		}
1597
5
		skip_until_mark();
1598
	}
1599
10
}
1600
1601
static void
1602
skip_until_mark(void)
1603
{
1604
	int ch;
1605
1606
125
	for (;;) {
1607
145
		ch = readch();
1608



145
		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
5
			(void)readreg();
1624
5
			if (readch() == 'e')
1625
				(void)readreg();
1626
			else
1627
5
				unreadch();
1628
			break;
1629
		case '[':
1630
5
			free(read_string(&bmachine.readstack[bmachine.readsp]));
1631
5
			break;
1632
		case '!':
1633
15
			switch (ch = readch()) {
1634
				case '<':
1635
				case '>':
1636
				case '=':
1637
10
					(void)readreg();
1638
10
					if (readch() == 'e')
1639
5
						(void)readreg();
1640
					else
1641
5
						unreadch();
1642
					break;
1643
				default:
1644
5
					free(readline());
1645
5
					break;
1646
			}
1647
			break;
1648
		default:
1649
			break;
1650
		}
1651
	}
1652
5
}
1653
1654
static void
1655
parse_number(void)
1656
{
1657
193980
	unreadch();
1658
193980
	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1659
96990
	    bmachine.ibase));
1660
96990
}
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
52230
	if (bmachine.readsp > 0) {
1675
		/* Check for tail call. Do not recurse in that case. */
1676
25605
		ch = readch();
1677
25605
		if (ch == EOF) {
1678
14115
			src_free();
1679
14115
			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1680
14115
			return;
1681
		} else
1682
11490
			unreadch();
1683
11490
	}
1684
12000
	if (bmachine.readsp == bmachine.readstack_sz - 1) {
1685
50
		size_t newsz = bmachine.readstack_sz * 2;
1686
		struct source *stack;
1687
50
		stack = reallocarray(bmachine.readstack, newsz,
1688
		    sizeof(struct source));
1689
50
		if (stack == NULL)
1690
			err(1, "recursion too deep");
1691
50
		bmachine.readstack_sz = newsz;
1692
50
		bmachine.readstack = stack;
1693
50
	}
1694
12000
	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1695
38115
}
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
22730
	p = pop_string();
1716
11365
	if (p != NULL)
1717
11365
		eval_string(p);
1718
11365
}
1719
1720
void
1721
eval(void)
1722
{
1723
	int	ch;
1724
1725
645065
	for (;;) {
1726
651790
		ch = readch();
1727
651790
		if (ch == EOF) {
1728
6960
			if (bmachine.readsp == 0)
1729
				return;
1730
6860
			src_free();
1731
6860
			bmachine.readsp--;
1732
6860
			continue;
1733
		}
1734
644830
		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
644830
		if (0 <= ch && ch < UCHAR_MAX)
1750
644830
			(*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
100
}