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