GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/dc/bcode.c Lines: 649 787 82.5 %
Date: 2017-11-07 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
243
	bmachine.extended_regs = extended_registers;
233
243
	bmachine.reg_array_size = bmachine.extended_regs ?
234
	    REG_ARRAY_SIZE_BIG : REG_ARRAY_SIZE_SMALL;
235
236
243
	bmachine.reg = calloc(bmachine.reg_array_size,
237
	    sizeof(bmachine.reg[0]));
238
243
	if (bmachine.reg == NULL)
239
		err(1, NULL);
240
241
124416
	for (i = 0; i < UCHAR_MAX; i++)
242
61965
		jump_table[i] = unknown;
243
35478
	for (i = 0; i < JUMP_TABLE_DATA_SIZE; i++)
244
17496
		jump_table[jump_table_data[i].ch] = jump_table_data[i].f;
245
246
243
	stack_init(&bmachine.stack);
247
248
31975398
	for (i = 0; i < bmachine.reg_array_size; i++)
249
15987456
		stack_init(&bmachine.reg[i]);
250
251
243
	bmachine.readstack_sz = READSTACK_SIZE;
252
243
	bmachine.readstack = calloc(sizeof(struct source),
253
	    bmachine.readstack_sz);
254
243
	if (bmachine.readstack == NULL)
255
		err(1, NULL);
256
243
	bmachine.obase = bmachine.ibase = 10;
257
243
	(void)signal(SIGINT, sighandler);
258
243
}
259
260
u_int
261
bmachine_scale(void)
262
{
263
88236
	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
486
	bmachine.readsp = 0;
271
243
	bmachine.readstack[0] = *src;
272
243
}
273
274
static __inline int
275
readch(void)
276
{
277
3312342
	struct source *src = &bmachine.readstack[bmachine.readsp];
278
279
1656171
	return src->vtable->readchar(src);
280
}
281
282
static __inline void
283
unreadch(void)
284
{
285
492462
	struct source *src = &bmachine.readstack[bmachine.readsp];
286
287
246231
	src->vtable->unreadchar(src);
288
246231
}
289
290
static __inline char *
291
readline(void)
292
{
293
24030
	struct source *src = &bmachine.readstack[bmachine.readsp];
294
295
12015
	return src->vtable->readline(src);
296
}
297
298
static __inline void
299
src_free(void)
300
{
301
94014
	struct source *src = &bmachine.readstack[bmachine.readsp];
302
303
47007
	src->vtable->free(src);
304
47007
}
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
399312
	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
454302
	if (s == 0)
348
125892
		return;
349
350
101259
	abs_scale = s > 0 ? s : -s;
351
352
101259
	if (abs_scale < sizeof(factors)/sizeof(factors[0])) {
353
75852
		if (s > 0)
354
75816
			bn_check(BN_mul_word(n, factors[abs_scale]));
355
		else
356
36
			(void)BN_div_word(n, factors[abs_scale]);
357
	} else {
358
		BIGNUM *a, *p;
359
		BN_CTX *ctx;
360
361
25407
		a = BN_new();
362
25407
		bn_checkp(a);
363
25407
		p = BN_new();
364
25407
		bn_checkp(p);
365
25407
		ctx = BN_CTX_new();
366
25407
		bn_checkp(ctx);
367
368
25407
		bn_check(BN_set_word(a, 10));
369
25407
		bn_check(BN_set_word(p, abs_scale));
370
25407
		bn_check(BN_exp(a, a, p, ctx));
371
25407
		if (s > 0)
372
18963
			bn_check(BN_mul(n, n, a, ctx));
373
		else
374
6444
			bn_check(BN_div(n, NULL, n, a, ctx));
375
25407
		BN_CTX_free(ctx);
376
25407
		BN_free(a);
377
25407
		BN_free(p);
378
	}
379
328410
}
380
381
void
382
split_number(const struct number *n, BIGNUM *i, BIGNUM *f)
383
{
384
	u_long rem;
385
386
185922
	bn_checkp(BN_copy(i, n->number));
387
388
92961
	if (n->scale == 0 && f != NULL)
389
29754
		bn_check(BN_set_word(f, 0));
390
63207
	else if (n->scale < sizeof(factors)/sizeof(factors[0])) {
391
57429
		rem = BN_div_word(i, factors[n->scale]);
392
57429
		if (f != NULL)
393
19017
			bn_check(BN_set_word(f, rem));
394
	} else {
395
		BIGNUM *a, *p;
396
		BN_CTX *ctx;
397
398
5778
		a = BN_new();
399
5778
		bn_checkp(a);
400
5778
		p = BN_new();
401
5778
		bn_checkp(p);
402
5778
		ctx = BN_CTX_new();
403
5778
		bn_checkp(ctx);
404
405
5778
		bn_check(BN_set_word(a, 10));
406
5778
		bn_check(BN_set_word(p, n->scale));
407
5778
		bn_check(BN_exp(a, a, p, ctx));
408
5778
		bn_check(BN_div(i, f, n->number, a, ctx));
409
5778
		BN_CTX_free(ctx);
410
5778
		BN_free(a);
411
5778
		BN_free(p);
412
	}
413
92961
}
414
415
void
416
normalize(struct number *n, u_int s)
417
{
418
414648
	scale_number(n->number, s - n->scale);
419
207324
	n->scale = s;
420
207324
}
421
422
static u_long
423
get_ulong(struct number *n)
424
{
425
30420
	normalize(n, 0);
426
15210
	return BN_get_word(n->number);
427
}
428
429
void
430
negate(struct number *n)
431
{
432
828
	BN_set_negative(n->number, !BN_is_negative(n->number));
433
414
}
434
435
static __inline void
436
push_number(struct number *n)
437
{
438
680580
	stack_pushnumber(&bmachine.stack, n);
439
340290
}
440
441
static __inline void
442
push_string(char *string)
443
{
444
13608
	stack_pushstring(&bmachine.stack, string);
445
6804
}
446
447
static __inline void
448
push(struct value *v)
449
{
450
371322
	stack_push(&bmachine.stack, v);
451
185661
}
452
453
static __inline struct value *
454
tos(void)
455
{
456
90810
	return stack_tos(&bmachine.stack);
457
}
458
459
static __inline struct value *
460
pop(void)
461
{
462
322272
	return stack_pop(&bmachine.stack);
463
}
464
465
static __inline struct number *
466
pop_number(void)
467
{
468
813780
	return stack_popnumber(&bmachine.stack);
469
}
470
471
static __inline char *
472
pop_string(void)
473
{
474
40914
	return stack_popstring(&bmachine.stack);
475
}
476
477
static __inline void
478
clear_stack(void)
479
{
480
54
	stack_clear(&bmachine.stack);
481
27
}
482
483
static __inline void
484
print_stack(void)
485
{
486
144
	stack_print(stdout, &bmachine.stack, "", bmachine.obase);
487
72
}
488
489
static __inline void
490
print_tos(void)
491
{
492
90810
	struct value *value = tos();
493
45405
	if (value != NULL) {
494
45405
		print_value(stdout, value, "", bmachine.obase);
495
90810
		(void)putchar('\n');
496
	}
497
	else
498
		warnx("stack empty");
499
45405
}
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
60408
	struct value *value = pop();
517
518
30204
	if (value != NULL) {
519
60408
		switch (value->type) {
520
		case BCODE_NONE:
521
			break;
522
		case BCODE_NUMBER:
523
17775
			normalize(value->u.num, 0);
524
17775
			print_ascii(stdout, value->u.num);
525
17775
			(void)fflush(stdout);
526
17775
			break;
527
		case BCODE_STRING:
528
12429
			(void)fputs(value->u.string, stdout);
529
12429
			(void)fflush(stdout);
530
12429
			break;
531
		}
532
30204
		stack_free_value(value);
533
30204
	}
534
30204
}
535
536
static void
537
pop_printn(void)
538
{
539
3222
	struct value *value = pop();
540
541
1611
	if (value != NULL) {
542
1611
		print_value(stdout, value, "", bmachine.obase);
543
1611
		(void)fflush(stdout);
544
1611
		stack_free_value(value);
545
1611
	}
546
1611
}
547
548
static __inline void
549
dup(void)
550
{
551
112986
	stack_dup(&bmachine.stack);
552
56493
}
553
554
static void
555
swap(void)
556
{
557
126
	stack_swap(&bmachine.stack);
558
63
}
559
560
static void
561
drop(void)
562
{
563
54
	struct value *v = pop();
564
27
	if (v != NULL)
565
27
		stack_free_value(v);
566
27
}
567
568
static void
569
get_scale(void)
570
{
571
	struct number	*n;
572
573
90
	n = new_number();
574
45
	bn_check(BN_set_word(n->number, bmachine.scale));
575
45
	push_number(n);
576
45
}
577
578
static void
579
set_scale(void)
580
{
581
	struct number	*n;
582
	u_long		scale;
583
584
234
	n = pop_number();
585
117
	if (n != NULL) {
586
117
		if (BN_is_negative(n->number))
587
			warnx("scale must be a nonnegative number");
588
		else {
589
117
			scale = get_ulong(n);
590
117
			if (scale != BN_MASK2 && scale <= UINT_MAX)
591
117
				bmachine.scale = (u_int)scale;
592
			else
593
				warnx("scale too large");
594
			}
595
117
		free_number(n);
596
117
	}
597
117
}
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
11322
	n = pop_number();
616
5661
	if (n != NULL) {
617
5661
		base = get_ulong(n);
618
5661
		if (base != BN_MASK2 && base > 1 && base <= UINT_MAX)
619
5661
			bmachine.obase = (u_int)base;
620
		else
621
			warnx("output base must be a number greater than 1");
622
5661
		free_number(n);
623
5661
	}
624
5661
}
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
72
	n = pop_number();
643
36
	if (n != NULL) {
644
36
		base = get_ulong(n);
645
36
		if (base != BN_MASK2 && 2 <= base && base <= 16)
646
36
			bmachine.ibase = (u_int)base;
647
		else
648
			warnx("input base must be a number between 2 and 16 "
649
			    "(inclusive)");
650
36
		free_number(n);
651
36
	}
652
36
}
653
654
static void
655
stackdepth(void)
656
{
657
	size_t i;
658
	struct number *n;
659
660
36
	i = stack_size(&bmachine.stack);
661
18
	n = new_number();
662
18
	bn_check(BN_set_word(n->number, i));
663
18
	push_number(n);
664
18
}
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
126
	value = pop();
675
63
	if (value != NULL) {
676
108
		switch (value->type) {
677
		case BCODE_NONE:
678
			return;
679
		case BCODE_NUMBER:
680
45
			scale = value->u.num->scale;
681
45
			break;
682
		case BCODE_STRING:
683
			break;
684
		}
685
63
		stack_free_value(value);
686
63
		n = new_number();
687
63
		bn_check(BN_set_word(n->number, scale));
688
63
		push_number(n);
689
63
	}
690
126
}
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
5868
	if (BN_is_zero(n->number))
699
36
		return n->scale ? n->scale : 1;
700
701
2916
	int_part = new_number();
702
2916
	fract_part = new_number();
703
2916
	fract_part->scale = n->scale;
704
2916
	split_number(n, int_part->number, fract_part->number);
705
706
	i = 0;
707
28692
	while (!BN_is_zero(int_part->number)) {
708
11430
		(void)BN_div_word(int_part->number, 10);
709
11430
		i++;
710
	}
711
2916
	free_number(int_part);
712
2916
	free_number(fract_part);
713
2916
	return i + n->scale;
714
2934
}
715
716
static void
717
num_digits(void)
718
{
719
	struct value	*value;
720
	size_t		digits;
721
	struct number	*n = NULL;
722
723
5922
	value = pop();
724
2961
	if (value != NULL) {
725

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

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

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

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

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

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

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

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

26424
	switch (readch()) {
1420
	case '<':
1421
9009
		not_less();
1422
9009
		break;
1423
	case '>':
1424
2718
		not_greater();
1425
2718
		break;
1426
	case '=':
1427
1485
		not_equal();
1428
1485
		break;
1429
	default:
1430
		unreadch();
1431
		(void)fprintf(stderr, "! command is deprecated\n");
1432
		break;
1433
	}
1434
13212
}
1435
1436
static void
1437
not_less(void)
1438
{
1439
18018
	compare(BCODE_NOT_LESS);
1440
9009
}
1441
1442
static void
1443
greater(void)
1444
{
1445
1980
	compare(BCODE_GREATER);
1446
990
}
1447
1448
static void
1449
not_greater(void)
1450
{
1451
5436
	compare(BCODE_NOT_GREATER);
1452
2718
}
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
103086
	scale = max(a->scale, b->scale);
1461
1462
51543
	if (scale > a->scale)
1463
126
		normalize(a, scale);
1464
51417
	else if (scale > b->scale)
1465
9
		normalize(b, scale);
1466
1467
51543
	cmp = BN_cmp(a->number, b->number);
1468
1469
51543
	free_number(a);
1470
51543
	free_number(b);
1471
1472

51543
	switch (type) {
1473
	case BCODE_EQUAL:
1474
19539
		return cmp == 0;
1475
	case BCODE_NOT_EQUAL:
1476
1485
		return cmp != 0;
1477
	case BCODE_LESS:
1478
17748
		return cmp < 0;
1479
	case BCODE_NOT_LESS:
1480
9009
		return cmp >= 0;
1481
	case BCODE_GREATER:
1482
990
		return cmp > 0;
1483
	case BCODE_NOT_GREATER:
1484
2772
		return cmp <= 0;
1485
	}
1486
	return false;
1487
51543
}
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
102672
	idx = readreg();
1499
51336
	if (readch() == 'e')
1500
387
		elseidx = readreg();
1501
	else
1502
50949
		unreadch();
1503
1504
51336
	a = pop_number();
1505
51336
	if (a == NULL)
1506
		return;
1507
51336
	b = pop_number();
1508
51336
	if (b == NULL) {
1509
		push_number(a);
1510
		return;
1511
	}
1512
1513
51336
	ok = compare_numbers(type, a, b);
1514
1515
51336
	if (!ok && elseidx != NO_ELSE)
1516
216
		idx = elseidx;
1517
1518

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

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

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



261
		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
9
			(void)readreg();
1624
9
			if (readch() == 'e')
1625
				(void)readreg();
1626
			else
1627
9
				unreadch();
1628
			break;
1629
		case '[':
1630
9
			free(read_string(&bmachine.readstack[bmachine.readsp]));
1631
9
			break;
1632
		case '!':
1633
27
			switch (ch = readch()) {
1634
				case '<':
1635
				case '>':
1636
				case '=':
1637
18
					(void)readreg();
1638
18
					if (readch() == 'e')
1639
9
						(void)readreg();
1640
					else
1641
9
						unreadch();
1642
					break;
1643
				default:
1644
9
					free(readline());
1645
9
					break;
1646
			}
1647
			break;
1648
		default:
1649
			break;
1650
		}
1651
	}
1652
9
}
1653
1654
static void
1655
parse_number(void)
1656
{
1657
349164
	unreadch();
1658
349164
	push_number(readnumber(&bmachine.readstack[bmachine.readsp],
1659
174582
	    bmachine.ibase));
1660
174582
}
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
94014
	if (bmachine.readsp > 0) {
1675
		/* Check for tail call. Do not recurse in that case. */
1676
46089
		ch = readch();
1677
46089
		if (ch == EOF) {
1678
25407
			src_free();
1679
25407
			src_setstring(&bmachine.readstack[bmachine.readsp], p);
1680
25407
			return;
1681
		} else
1682
20682
			unreadch();
1683
20682
	}
1684
21600
	if (bmachine.readsp == bmachine.readstack_sz - 1) {
1685
90
		size_t newsz = bmachine.readstack_sz * 2;
1686
		struct source *stack;
1687
90
		stack = reallocarray(bmachine.readstack, newsz,
1688
		    sizeof(struct source));
1689
90
		if (stack == NULL)
1690
			err(1, "recursion too deep");
1691
90
		bmachine.readstack_sz = newsz;
1692
90
		bmachine.readstack = stack;
1693
90
	}
1694
21600
	src_setstring(&bmachine.readstack[++bmachine.readsp], p);
1695
68607
}
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
40914
	p = pop_string();
1716
20457
	if (p != NULL)
1717
20457
		eval_string(p);
1718
20457
}
1719
1720
void
1721
eval(void)
1722
{
1723
	int	ch;
1724
1725
486
	for (;;) {
1726
1173222
		ch = readch();
1727
1173222
		if (ch == EOF) {
1728
12528
			if (bmachine.readsp == 0)
1729
				return;
1730
12348
			src_free();
1731
12348
			bmachine.readsp--;
1732
12348
			continue;
1733
		}
1734
1160694
		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
1160694
		if (0 <= ch && ch < UCHAR_MAX)
1750
1160694
			(*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
180
}